2

Note: I'm new to django rest framework. First project with it. My model has a foreign key which in the serializer I link by a SlugRelatedField. This related model is a small list of options that can be selected however what is available for selection depends on the user (or more specifically the user group).

I have found this question that says how to get the user into a serilaizer. But this doesn't seem to help as the field definition is static right?

Removing the irrelevant parts I have:

class MyModelSerializer(serializers.ModelSerializer):

        sequence =  serializers.SlugRelatedField(
        many=False,
        read_only=False,
        slug_field='prefix',
        queryset=Sequence.objects.filter(active=True,
                sequence_groups__sequence_group_id__in=SequenceGroup.objects.filter(users=serializers.CurrentUserDefault()))
    )

This query works as I also use it in a normal form. When I start the dev. server I get an exception:

TypeError: int() argument must be a string, a bytes-like object or a number, not 'CurrentUserDefault'

So my question is how can I get the current user into the queryset of the SlugRelatedField?

beginner_
  • 7,230
  • 18
  • 70
  • 127

1 Answers1

1

It's funny how after hours of trying, writing down the question leads one to a working solution.

  1. Add request to sterilizer context in ModelViewSet

    Simply add below method to the ModelViewSet:

    def get_serializer_context(self):
        return {"request": self.request}
    
  2. Adjust the queryset of the SlugRelatedField in the constructor of the Serializer

    def __init__(self, *args, **kwargs):
        super(MyModelSerializer, self).__init__(*args, **kwargs)
        # superuser can choose from all sequences, normal users can only choose from
        # active sequences he is assigned to
        request = self.context.get("request")
        if request and hasattr(request, "user"):
            sequence = self.fields['sequence']
            if request.user.is_superuser:
                sequence.queryset = Sequence.objects.all()
            else:
                sequence.queryset = Sequence.objects.filter(active=True,
                        sequence_groups__sequence_group_id__in=SequenceGroup.objects.filter(users=request.user))
    

In my case the admin should be able to select any of the available options hence the extra condition.

beginner_
  • 7,230
  • 18
  • 70
  • 127