Tastypie PATCH请求无效,但返回202 ACCEPTED

时间:2014-10-14 15:03:56

标签: python django curl tastypie

我有自定义用户模型和资源端点,由于某种原因,发送PATCH请求导致HTTP / 1.1 202 ACCEPTED,但没有更改生效。

通过阅读文档,似乎我必须手动抓取模型并自行更新字段。 E.g:

AppUser.objects.all().select_related('api_key').set(params)`)

相反,这应该构建在Tastypie中,对吗?

http://django-tastypie.readthedocs.org/en/latest/resources.html#Resource.obj_update

在这里说ModelResource(我正在使用)具有“特定于Django模型的完整工作版本”。那是什么给出了什么?

我正在制作的卷曲请求是这样的:

curl -X PATCH -H "Authorization: Basic XXX" -H "X-CSRFToken:XXX" \
--cookie "sessionid=XXX; csrftoken=XXX" --data '{"last_name": "meee"}' \
http://localhost:8000/api/v1/user/1/?format=json --verbose | python -mjson.tool

从我的models.py:

"""
Custom User Model.
"""
class AppUser(AbstractUser):
    """
    User model to which all other information about the user is linked 
    (e.g. the language they speak, the language they're learning, and 
    the submissions they make (submissions are stored in neo4j, see 
    api/submissions.py)
    """
    objects = UserManager()

    lang_learning = models.ForeignKey(Language, 
                            verbose_name='Learning Language', 
                            related_name='learning', 
                            null=True, 
                            help_text='Language the user is learning.')

    lang_speaking = models.ForeignKey(Language, 
                            verbose_name='Speaks Language', 
                            related_name='speaking', 
                            null=True, 
                            help_text='Language the user speaks.') 

    def __unicode__(self):
        return unicode(self.username) or u''

资源本身:

class UserResource(ModelResource):
    raw_password = fields.CharField(attribute=None, readonly=True,
                                    null=True, blank=True)

    lang_learning = fields.ForeignKey('api.language.LanguageResource', 
                                    'lang_learning', full=True, 
                                    blank=True, null=True)

    lang_speaking = fields.ForeignKey('api.language.LanguageResource', 
                                    'lang_speaking', full=True, 
                                    blank=True, null=True)

    class Meta:
        authentication = MultiAuthentication(
            BasicAuthentication(), ApiKeyAuthentication())
        serializer = urlencodeSerializer()
        authorization = CustomAuthorization()
        detail_allowed_methods = ['get', 'patch', 'put',]
        always_return_data = True
        queryset = AppUser.objects.all().select_related('api_key')
        excludes = ['is_active', 'is_staff', 'is_superuser', 'date_joined',
                    'last_login', 'password']

    def prepend_urls(self):
        params = (self._meta.resource_name, trailing_slash())

        return [
            url(r"^(?P<resource_name>%s)/login%s$" % params, 
                self.wrap_view('login'), name="api_login"),
            url(r"^(?P<resource_name>%s)/logout%s$" % params, 
                self.wrap_view('logout'), name="api_logout")
        ]

    def authorized_read_list(self, object_list, bundle):
        return object_list.filter(id=bundle.request.user.id).select_related()

    def get_list(self, request, **kwargs):
        kwargs['pk'] = request.user.pk
        return super(UserResource, self).get_detail(request, **kwargs)

    def obj_update(self, bundle, request=None, **kwargs):
        """
        Maybe it's something here I need to be doing?
        """
        for field_name in self.fields:
            field = self.fields[field_name]

            if type(field) is fields.ToOneField and field.null and bundle.data[field_name] is None:
                setattr(bundle.obj, field_name, None)

        return super(UserResource, self).obj_update(bundle, **kwargs)

    def hydrate(self, bundle):
        try:
            raw_password = bundle.data.pop('password')
            if not validate_password(raw_password):
                raise CustomBadRequest(
                    code='invalid_password',
                    message='Your password is invalid.')

            bundle.obj.set_password(raw_password)
        except KeyError:
            pass

        return bundle

    def dehydrate(self, bundle):
        if bundle.obj.pk == bundle.request.user.pk:
            bundle.data['key'] = bundle.obj.api_key.key

        return bundle

完整档案在这里: https://github.com/OpenPhilology/phaidra/blob/development/api/user.py

0 个答案:

没有答案