samu
samu

Reputation: 3120

Django Rest Framework - ForeignKey filtering in a serializer

I have two models, Fridge and Product. Fridge has a ForeignKey to auth.user, while Product has a ForeignKey to Fridge, simple enough.

Now quite obviously, I want an user to be able to add products only to his fridge. I want to create an API for that using DRF, AND I want a nice dropdown in the product viewset form, hence why I have to do this in a serializer. I'm using viewsets.ViewSet class, so get_serializer_context doesn't seem to have any effect.

class ProductSerializer(serializers.Serializer):
    pk = serializers.IntegerField(read_only=True)
    fridge = serializers.PrimaryKeyRelatedField(queryset=WHAT_QUERYSET)
    name = serializers.CharField(max_length=Product._meta.get_field('name').max_length)
    purchase_date = serializers.DateField()
    before_date = serializers.DateField()

I have no idea what should I put in the queryset keyword argument for the fridge attribute. I can't ask for request.user anywhere in that scope, as no context or request variables exist at that point.

Upvotes: 2

Views: 2679

Answers (1)

Gabriel Muj
Gabriel Muj

Reputation: 3815

What you need is dynamically queryset based on the user that makes the request. You can achieve this by overriding the __init__ method like this:

    def __init__(self, *args, **kwargs):
        super(ProductSerializer, self).__init__(*args, **kwargs)
        request_user = self.context['request'].user
        self.fields['fridge'].queryset = Fridge.objects.filter(user=request_user)

The initial field will have to look like this, since you have to specify the queryset othewise you will get an AssertionError:

    fridge = serializers.PrimaryKeyRelatedField(queryset=Fridge.objects.all())

but this will be overridden of course.

Upvotes: 4

Related Questions