Как фильтровать поля "многие ко многим" в моделях django

У меня есть 3 модели: User, Tag и Recipe. Модель User является базовой и не важна. Вот модель Tag:

class Tag(models.Model):
    name = models.CharField(max_length=255)
    user = models.ForeignKey(settings.AUTH_USER_MODEL , on_delete=CASCADE)

А вот модель Recipe:

class Recipe(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL , on_delete=CASCADE)
    title = models.CharField(max_length=255)
    tags = models.ManyToManyField('Tag',)

Я сделал конечную точку для всех этих моделей, но есть одна проблема! Когда я пытаюсь создать объект Recipe, все объекты Tag будут перечислены, но я хочу перечислить только теги зарегистрированных пользователей.

Вот мой Tag сериализатор:

class TagSerializer(serializers.ModelSerializer):

    class Meta:
        model = models.Tag
        fields = ('id' , 'name')
        extra_kwargs = {
            'id' : {
                'read_only' : True,
            }
        }

Вот мой набор представлений Tag:

class TagsView(RecipeAttrsView):

    queryset = models.Tag.objects.all()
    serializer_class = serializers.TagSerializer
    authentication_classes = (authentication.TokenAuthentication,)
    permission_classes = (permissions.IsAuthenticated,)

    def get_queryset(self):
        return self.queryset.filter(user=self.request.user)

    def perform_create(self, serializer):
        serializer.save(user=self.request.user)

Как отфильтровать теги, чтобы все перечисленные объекты тегов принадлежали вошедшему пользователю?

А queryset создается только один раз, то есть когда вы запускаете сервер. Поэтому атрибут queryset оценивается при запуске процесса, то есть при рендеринге вашей страницы, что приводит к выполнению представления class TagsView.

Метод get_queryset вызывается при каждом запросе, что может быть особенно полезно, если вы хотите динамически корректировать запрос, что, как мне кажется, вы пытаетесь сделать здесь. Таким образом, get_queryset - это метод, который предполагается использовать вместо переменной queryset в качестве альтернативы ей, обеспечивая большую гибкость.

Вам действительно не нужны оба вместе, что может быть причиной вашей проблемы. Вы можете просто сделать это следующим образом.

class TagsView(RecipeAttrsView):

    serializer_class = serializers.TagSerializer
    authentication_classes = (authentication.TokenAuthentication,)
    permission_classes = (permissions.IsAuthenticated,)

    def get_queryset(self):
        return models.Tags.objects.filter(user=self.request.user)

    def perform_create(self, serializer):
        serializer.save(user=self.request.user)
Вернуться на верх