Tastypie Update(PUT)用户名按关系导致密码消失。

时间:2013-10-09 17:00:46

标签: python django tastypie

我在ModelResource的Meta类中遇到excludes属性的麻烦。

我为User创建了ModelResource。

class UserResource(ModelResource):
    class Meta:
        serializer = Serializer(formats=['json'])
        queryset = User.objects.all()
        excludes = ['password', 'is_active', 'is_staff', 'is_superuser']
        resource_name = 'user'
        always_return_data = True
        authentication = ApiKeyAuthentication()
        authorization = UserAuthorization()

doc.

中的那个很相似

我发送PUT以更新username:\ n     {"username": "bara", "first_name": "bara", "last_name": "", "email": "bara@example.com", "last_login": "2013-10-09T15:32:55.056235","id": 7, "date_joined": "2013-10-09T15:32:55.056235"}

一切都很完美。

但是我不想直接使用这个资源我想用这个。

class ProfileResource(ModelResource):
    user = fields.ToOneField(UserResource, 'user', full=True)

    class Meta:
        serializer = Serializer(formats=['json'])
        queryset = Profile.objects.all()
        resource_name = 'profile'
        excludes = ['created', 'modified']
        always_return_data = True
        authentication = ApiKeyAuthentication()
        authorization = ProfileAuthorization()
        ...

我发送PUT以更新username:     { "user": {"username": "barabara", "first_name": "bara", "last_name": "", "email": "bara@example.com", "last_login": "2013-10-09T15:32:55.056235", "id": 7, "date_joined": "2013-10-09T15:32:55.056235"}, "gender": 0, "birth_date": null}

它似乎运作良好,但事实并非如此。在第二种情况下,密码以某种方式被覆盖。 我得到ValueError: Unknown password hashing algorithm.
在管理面板中,我看到: enter image description here

我尝试在ProfileResource的Meta中设置excludes,如user__passwordpassword,但似乎无效。

其他信息:
- 用户和个人资料是一对一的关系 - Python 2.7,Django 1.4.3,Tastypie 0.9.12

编辑:
我很抱歉令人困惑但这只发生在username更新期间。用户的所有其余字段都可以正常工作。

2 个答案:

答案 0 :(得分:0)

我不确定,但我认为问题是当你执行put时会创建新用户,因为它会更新用户字段(例如用新的用户字段替换现有的用户字段,它没有密码字段,它不会合并这两个用户。)

也许尝试使用其他动词?

答案 1 :(得分:0)

我必须实现脏黑客仍然没有经过良好测试,所以请小心:
ProfileResource的方法:

def obj_update(self, bundle, **kwargs):
        """
        Additional operations for changing username.

        Changes username in database.
        """
        bundle = super(ProfileResource, self).obj_update(bundle, **kwargs)

        username, api_key = self.get_credentials(bundle.request)
        profile = Profile.get_logged(username, api_key)
        if profile:
            try:
                if bundle.data['username'] and bundle.data['username'] != profile.user.username:
                    try:
                        User.objects.get(username=bundle.data['username'])
                        logging.warning('Username %s Already exists cannot update.' % bundle.data['username'])
                    except User.DoesNotExist:
                        profile.user.username = bundle.data['username']
                        profile.user.save()

            except KeyError:
                pass

        return bundle

我知道这不是解决方案。其他选项是直接使用UserResource