我有自定义用户模型和资源端点,由于某种原因,发送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