django-rest-framework PUT重写只读slug字段

时间:2013-05-02 06:30:27

标签: put django-rest-framework

首先,我重写了我的视图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中所述。是不是正确处理我的案子?或者我应该做些什么来规避这种行为?

1 个答案:

答案 0 :(得分:0)

pk和/或slug在pre_save方法中设置,因为它们隐含在URL中。 (与序列化程序处理的请求数据相反。)

如果你真的需要改变行为,你可以通过覆盖pre_save方法来改变行为,虽然对我来说并不是很明显为什么你需要它来做一些不同的事情。

the field gets updated with the URL-encoded version

当然这是正确的 - 如果对象确实存在并且已经通过URL中的slug查找,那么从URL设置slug字段实际上不会改变它。如果对象不存在,则需要设置slug。