The Django Request Framework "ManyRelatedField" object does not have a "queryset" attribute when changing a request in get_fields

I get the following error in GET /api/stories/169/ in the StorySerializer, noted below in a comment:

 AttributeError at /api/stories/169/ 'ManyRelatedField' object has no attribute 'queryset' 

After checking the object, I found that if I changed the line from ...

 fields['feature'].queryset = fields['feature'].queryset.filter(user=user) 

to

 fields['photos'].child_relation.queryset = fields['photos'].child_relation.queryset.filter(user=user) 

... it looks like it works. But this approach is undocumented, and I'm sure this is the wrong way to do it.

I have these models:

 class Story(CommonInfo): user = models.ForeignKey(User) text = models.TextField(max_length=5000,blank=True) feature = models.ForeignKey("Feature", blank=True, null=True) tags = models.ManyToManyField("Tag") class Feature(CommonInfo): user = models.ForeignKey(User) name = models.CharField(max_length=50) class Photo(CommonInfo): user = models.ForeignKey(User) image = ImageField(upload_to='photos') story = models.ForeignKey("Story", blank=True, null=True, related_name='photos', on_delete=models.SET_NULL) 

And StorySerializer :

 class StorySerializer(serializers.HyperlinkedModelSerializer): user = serializers.CharField(read_only=True) comments = serializers.HyperlinkedRelatedField(read_only=True, view_name='comment-detail', many=True) def get_fields(self, *args, **kwargs): user = self.context['request'].user fields = super(StorySerializer, self).get_fields(*args, **kwargs) ## Restrict the options that the user can pick to the Features ## and Photos that they own # This line works: fields['feature'].queryset = fields['feature'].queryset.filter(user=user) # This line throws the error: fields['photos'].queryset = fields['photos'].queryset.filter(user=user) return fields class Meta: model = Story fields = ('url', 'user', 'text', 'comments', 'photos', 'feature', 'tags') 

What am I doing wrong? I feel this is related to the direction of the ForeignKey relationship.

+7
source share
1 answer

I had a similar problem and found a solution (related) related to the default set of queries for a nested serializer: How to filter a nested serializer in the Django Rest Framework?

Instead of editing get_fields in the story serializer, add function and photo fields that reference function and photo serializers in the story serializer. For example, StorySerializer: features = FeatureSerializer(many=true, read_only=true) Then redefine list_serializer_class for the object and photo:

 class FeatureFilteredListSerializer(serializers.ListSerializer): def to_representation(self, data): data = data.filter(user=self.context['request'].user) return super(FeatureFilteredListSerializer, self).to_representation(data) // And then reference this from the actual FeatureSerializer meta: class FeatureSerializer(serializers.ModelSerializer): ... class Meta: model = Work list_serializer_class = FeatureFilteredListSerializer fields = (...) 

Then, when you reach the endpoint of your story, he will get this filtered list of nested serializers.

-1
source

Source: https://habr.com/ru/post/1216193/


All Articles