Limit queryset to foreignkey in django rest framework

Viewed 48

i searched a lot about a solution for this problem and i tried many solutions but no one solve it.

some of solutions i tried: limit choices to foreignkey and using CurrentUserDefault

the problem is i'm trying to limit the provider choices depending on the current user as each user has his own providers

i tried this code but gives me TypeError: Field 'id' expected a number but got CurrentUserDefault(),

Serializer:

class RideSerializer(serializers.ModelSerializer):

    invoice = InvoiceSerializer(required=False)
    duration = serializers.ReadOnlyField()
    riding_duration = serializers.ReadOnlyField()
    heading_duration = serializers.ReadOnlyField()
    earning_per_km = serializers.ReadOnlyField()
    earning_per_minute = serializers.ReadOnlyField()
    provider = serializers.PrimaryKeyRelatedField(
        queryset=User.objects.select_related(
            'driver_profile__team', 'company_profile__team').filter(
            Q(driver_profile__team__user=serializers.CurrentUserDefault()) |
            Q(Company_profile__team__user=serializers.CurrentUserDefault())),
        default=serializers.CurrentUserDefault())

    class Meta:
        model = Ride
        exclude = ['shift', ]
        read_only_fields = ['id', 'start_time', ]

View:

class RideView(
        viewsets.GenericViewSet,
        mixins.UpdateModelMixin,
        mixins.RetrieveModelMixin,
        mixins.ListModelMixin,
        mixins.CreateModelMixin,):
    permission_classes = [IsDriver, ]
    serializer_class = RideSerializer
    http_method_names = ['post', 'patch', 'get']

    def get_queryset(self):
        return super().get_queryset().select_related(
            'shift', "invoice").filter(shift__driver=self.request.user.driver_profile)

    def create(self, request, *args, **kwargs):
        self.serializer = self.get_serializer(
            data=request.data, context={'request': request})
        return super().create(request, *args, **kwargs)
1 Answers

Set the queryset to an empty one in your field definitions and override it in a custom constructor. Furthermore, it is a good idea to move this query into a custom model manager https://docs.djangoproject.com/en/4.1/topics/db/managers/.

  class RideSerializer(serializers.ModelSerializer):
    # ....
    provider = serializers.PrimaryKeyRelatedField(
        queryset=User.objects.none())

    def __init__(self, *args, **kwargs):
       super().__init__(*args, **kwargs)
       self.fields["provider"].queryset = User.objects.select_related(
            'driver_profile__team', 'company_profile__team').filter(
            Q(driver_profile__team__user=request.user) |
            Q(Company_profile__team__user=request.user))

    class Meta:
        model = Ride
        exclude = ['shift', ]
        read_only_fields = ['id', 'start_time', ]
Related