Как фильтровать поля "многие ко многим" в моделях 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)