Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django TastyPie正确放置嵌套用户模型_Django_Django Models_Tastypie - Fatal编程技术网

Django TastyPie正确放置嵌套用户模型

Django TastyPie正确放置嵌套用户模型,django,django-models,tastypie,Django,Django Models,Tastypie,我正在尝试使用Django TastyPie来更新我的模型。我有一个身份模型,充当默认Django用户模型的包装器: class Identity(ProfileBase): user = models.OneToOneField(User, related_name='identity') avatar = models.ImageField(upload_to=avatar_upload_path, blank=True, null=True) 我有我的用户

我正在尝试使用Django TastyPie来更新我的模型。我有一个身份模型,充当默认Django用户模型的包装器:

class Identity(ProfileBase):
    user = models.OneToOneField(User, related_name='identity')
    avatar = models.ImageField(upload_to=avatar_upload_path, blank=True,
        null=True)
我有我的
用户资源

class UserResource(ModelResource):

    class Meta:
        resource_name = 'user'
        queryset = User.objects.all()
        fields = ['email', 'first_name', 'last_name']
        include_resource_uri = False
class IdentityResource(ModelResource):
    user = fields.ToOneField(UserResource, 'user', full=True)

    class Meta:
        resource_name = 'identity'
        queryset = Identity.objects.select_related()
        fields = ['user', 'avatar']
        always_return_data = True
        include_resource_uri = False

        authentication = OAuthTokenAuthentication()
        authorization = Authorization()
def obj_update(self, bundle, request, **kwargs):
    print 'updating object'
    bundle = self.full_hydrate(bundle)
    bundle.obj.user = request.user
    user = bundle.data['user']
    bundle.obj.user.first_name = user['first_name']
    bundle.obj.user.last_name = user['last_name']
    return super(IdentityResource, self).obj_update(bundle, request, user=request.user)
我有我的
身份资源

class UserResource(ModelResource):

    class Meta:
        resource_name = 'user'
        queryset = User.objects.all()
        fields = ['email', 'first_name', 'last_name']
        include_resource_uri = False
class IdentityResource(ModelResource):
    user = fields.ToOneField(UserResource, 'user', full=True)

    class Meta:
        resource_name = 'identity'
        queryset = Identity.objects.select_related()
        fields = ['user', 'avatar']
        always_return_data = True
        include_resource_uri = False

        authentication = OAuthTokenAuthentication()
        authorization = Authorization()
def obj_update(self, bundle, request, **kwargs):
    print 'updating object'
    bundle = self.full_hydrate(bundle)
    bundle.obj.user = request.user
    user = bundle.data['user']
    bundle.obj.user.first_name = user['first_name']
    bundle.obj.user.last_name = user['last_name']
    return super(IdentityResource, self).obj_update(bundle, request, user=request.user)
我当前正在使用
IdentityResource
中的ModelResource
obj\u update
方法成功更新名字和姓氏:

class UserResource(ModelResource):

    class Meta:
        resource_name = 'user'
        queryset = User.objects.all()
        fields = ['email', 'first_name', 'last_name']
        include_resource_uri = False
class IdentityResource(ModelResource):
    user = fields.ToOneField(UserResource, 'user', full=True)

    class Meta:
        resource_name = 'identity'
        queryset = Identity.objects.select_related()
        fields = ['user', 'avatar']
        always_return_data = True
        include_resource_uri = False

        authentication = OAuthTokenAuthentication()
        authorization = Authorization()
def obj_update(self, bundle, request, **kwargs):
    print 'updating object'
    bundle = self.full_hydrate(bundle)
    bundle.obj.user = request.user
    user = bundle.data['user']
    bundle.obj.user.first_name = user['first_name']
    bundle.obj.user.last_name = user['last_name']
    return super(IdentityResource, self).obj_update(bundle, request, user=request.user)
我想发出
请求,并有选择地更新用户或身份模型上的任何字段(用户的名字、姓氏或身份上的化身字段)。我不想像上面所做的那样,从捆绑数据手动访问每个字段并在模型上手动设置它们


我如何在TastyPie中自然地做到这一点?有人能解释一下解决这个问题的更好方法吗?非常感谢您的指导。:)

你可以这样做

# Find all properties in user model.
properties = [prop for prop in bunder.obj.user if not prop.startswith('__')]
bundle_user = bundle.data['user']
# Find the property in bundle user and set it back on user if it exists.
for property in properties:
  if property in bundle_user:
    setattr(bundle.obj.user, property, bundle_user[property])

也许我没有抓住要点,但是您是否尝试了
补丁
-方法请求?Tastypie将获取所有发送的属性,并在数据库中更新它们,使所有not send属性保持不变。

以下是我尝试提供一个尽可能利用Tastypie的答案的机会

它比OP的请求更通用(它将更新任何用户,而不仅仅是登录的用户)。在现实世界中,您可能需要添加某种身份验证/授权

from tastypie.resources import ModelResource
from tastypie.authorization import Authorization
from django.contrib.auth.models import User
from myapp.account.models import Identity

class IdentityResource(ModelResource):
    class Meta:
        queryset = Identity.objects.all()


class UserResource(ModelResource):
    class Meta:
        queryset = User.objects.all()
        allowed_list_methods = ['get']
        allowed_detail_methods = ['get','put']
        authorization = Authorization()

    def dehydrate(self, bundle):
        identity_bundle = self.build_identity_bundle(bundle)
        identity_bundle = IdentityResource().full_dehydrate(identity_bundle)
        return identity_bundle

    def obj_update(self, bundle, request, **kwargs):
        user_bundle = super(UserResource, self).obj_update(bundle, request, **kwargs)
        identity_bundle = self.build_identity_bundle(user_bundle)
        IdentityResource().obj_update(identity_bundle, request)
        return user_bundle

    def build_identity_bundle(self, user_bundle):
        identity_bundle = IdentityResource().build_bundle(
                obj=user_bundle.obj.get_profile(),
                data=user_bundle.data
            )
        return identity_bundle
该示例支持的是:

  • 获取平坦的用户+标识资源
  • 放置平坦的用户+标识资源,更新两个模型

您可能希望在API中注册UserResource,而不是IdentityResource。

我已经设置了一个悬赏,因此这个问题有望得到更多的关注,有人会提供可以被视为规范的答案(希望如此)。许多人遇到了类似的问题,因为这是Django处理用户信息扩展的标准实践(通过添加与用户模型一对一相关的新模型)。人们只需要记住另外一件事:这个解决方案通常使用的信号,它会自动创建分配给用户实例的Identity/UserProfile实例。从这样的关系创建用户不是很危险吗?您将如何设置密码并通知他们?我不会写这样的通用解决方案,因为它们可能会导致下游的安全问题。看起来您正在更新当前登录的用户。那是故意的吗?我怀疑。obj_update更新当前登录用户帐户的位置是否错误?这不是为了在系统中创建新用户。您正在尝试迭代模型实例,甚至不检查它是字段、方法还是常量。有一种方法可以获取资源中的字段列表,它考虑了字段排除。Fundamol感谢您的建议,这不是一种糟糕的方法@塔德克,你能提供你在这里所说的吗?@kyleturner:也许不可怕,但不太好用。我所说的功能是:,还有更多。。。这里的问题是,这个答案没有使用它,也没有明确说明它以前已经被使用过(例如,由TastyPie本身使用)。@Tadeck Fair point。我试图用一个答案来解除障碍,不一定是一个带有Tastype的答案。我用了一些类似的东西,但不是在TastyPie中,所以我认为这可能会有所帮助。很抱歉这么晚了,但答案很棒。我已经用另一种方式工作了,但我想我会重构我所拥有的,以遵循您正在利用的所有可爱的Tastypie方法。非常感谢。