首先,我重写了我的视图get_object()
方法,以便对slug值进行URL解码(因为值包含斜杠,所以需要进行URL编码):
class MyDetail(generics.RetrieveUpdateAPIView):
def get_object(self, queryset=None):
...
slug = unquote(self.kwargs.get(self.slug_url_kwarg, None))
因此,虽然URL中的slug值是URL编码的,但模型中的数据却不是。 (也许有更好的方法来做到这一点;请告诉我。)
无论如何,这似乎有效,因为GET找到了正确的记录。但是,当我尝试执行PUT时,该字段会使用URL编码版本进行更新,即使它包含在序列化程序的元类“read_only_fields
成员中。”
问题似乎出现在mixins.py第152行的UpdateModelMixin
pre_save()
方法中:
def pre_save(self, obj):
...
if pk:
setattr(obj, 'pk', pk)
if slug:
setattr(obj, slug_field, slug)
这些似乎是支持通过PUT创建新资源,如https://github.com/tomchristie/django-rest-framework/issues/328中所述。是不是正确处理我的案子?或者我应该做些什么来规避这种行为?
答案 0 :(得分:0)
pk和/或slug在pre_save
方法中设置,因为它们隐含在URL中。 (与序列化程序处理的请求数据相反。)
如果你真的需要改变行为,你可以通过覆盖pre_save
方法来改变行为,虽然对我来说并不是很明显为什么你需要它来做一些不同的事情。
the field gets updated with the URL-encoded version
当然这是正确的 - 如果对象确实存在并且已经通过URL中的slug查找,那么从URL设置slug字段实际上不会改变它。如果对象不存在,则需要设置slug。