1

首先,我重写了视图的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's方法中:pre_save()

def pre_save(self, obj):
    ...
    if pk:
        setattr(obj, 'pk', pk)

    if slug:
        setattr(obj, slug_field, slug)

如https://github.com/tomchristie/django-rest-framework/issues/328中所述,这些似乎是为了支持通过 PUT 创建新资源。它没有正确处理我的案子吗?或者我应该做些什么来规避这种行为?

4

1 回答 1

0

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

如果你真的需要改变行为,你可以通过覆盖该pre_save方法来做到这一点,尽管我不清楚为什么你需要它来做一些不同的事情。

the field gets updated with the URL-encoded version

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

于 2013-05-02T09:01:11.720 回答