Django REST Serializer and unique_together and fro

2019-03-06 15:19发布

I am having trouble using the SlugRelatedField to deserialize a field that is part of unique_together set.

To given an example, I have a Blog model which has a Title and an Author. The tuple of these uniquely identify a Blog (as in the Title is unique to a given Author, but not unique site wide). I want to look up the Blog from a message containing just these values.

In order to deserialize a message (i.e. from_native), the SlugRelatedField calls: self.queryset.get(**{self.slug_field: data}) which will fail on the Title slug because it is not globally unique. This can be solved by providing a more limited queryset (ie one which contains just Blogs but that user), but I am not sure how/where is the best place to set this queryset in the Field (because I do not know the Author until I get to deserializing that field).

One idea would be to do my own deserialization of the Author in get_fields where I could then filter the queryset for Blog. This code is pretty ugly, likely results in deserialization of Author twice, and has issues when the Serializer is used for the list view (as opposed to the detail view).

1条回答
来,给爷笑一个
2楼-- · 2019-03-06 16:07

You need to set the QuerySet for your field at runtime.

You can do this in the serialiser, something like:

class MyObjectSerializer(serializers.HyperlinkedModelSerializer):
    def get_fields(self, *args, **kwargs):
       fields = super(MyObjectSerializer, self).get_fields(*args, **kwargs)
       fields['slug'].queryset = MyObject.objects.filter(self.context['view'].request.user)
       return fields

Or in the view as:

def get_serializer(self):
    serializer = super(MyObjectView, self).get_serializer()
    serializer.fields['slug'].queryset = MyObject.objects.filter(self.request.user)

It's the same thing — you're setting the QuerySet on the slug field once you have a reference to the current user — it just depends on which is best for you.

I hope that helps.

查看更多
登录 后发表回答