Как я могу отфильтровать ManyToManyField против текущего пользователя в API-интерфейсе просмотра в DRF? - PullRequest
0 голосов
/ 09 мая 2018

У меня 2 модели, Todo и Tag. У Todo есть отношения ManyToMany с Tag. При добавлении новых Todos из Browsable API я хочу видеть только теги, добавленные текущим пользователем, в качестве доступных параметров в множественном выборе. В настоящее время отображаются все добавленные теги, независимо от того, кто их добавил. Я хочу ограничить параметры, чтобы показывать только теги, добавленные текущим пользователем. (Аутентификация уже настроена)

Модели:

class Todo(models.Model):
    title = models.CharField(max_length=100)
    description = models.TextField(blank=True)

    created_at = models.DateTimeField(auto_now_add=True)
    due_at = models.DateTimeField(blank=True)
    updated_at = models.DateTimeField(auto_now=True)

    tags = models.ManyToManyField(Tag, related_name='todos')

    creator = models.ForeignKey(User, on_delete=models.CASCADE, related_name='todos')

class Tag(models.Model):
    name = models.CharField(max_length=20)
    creator = models.ForeignKey(User, on_delete=models.CASCADE, related_name='created_tags')

    def __str__(self):
        return self.name

Сериализатор:

class TodoCreateSerializer(serializers.ModelSerializer): #This is the one being used for a POST
    class Meta:
        model = models.Todo
        fields = ('title', 'description', 'due_at', 'tags')

Есть ли поле сериализатора или какой-либо другой способ указать, какой набор запросов использовать в сериализаторе? Есть ли другой лучший подход?

1 Ответ

0 голосов
/ 10 мая 2018

В вашем TodoCreateSerializer необходимо добавить PrimaryKeyRelatedField с пользовательским queryset, в котором есть отфильтрованные теги пользователя.

Во-первых, вам нужно создать пользовательский PrimaryKeyRelatedField, который фильтрует любые объекты, чтобы получить доступ только к тем, кто принадлежит пользователю.

class UserFilteredPrimaryKeyRelatedField(serializers.PrimaryKeyRelatedField):
    def get_queryset(self):
        request = self.context.get('request', None)
        queryset = super(UserFilteredPrimaryKeyRelatedField, self).get_queryset()
        if not request or not queryset:
            return None
        return queryset.filter(user=request.user)

(Это универсальный вариант, который можно использовать при фильтрации объектов по user)

Тогда тебе следует использовать это в себе TodoCreateSerializer:

class TodoCreateSerializer(serializers.ModelSerializer): 
    tags = UserFilteredPrimaryKeyRelatedField(queryset= Tag.objects, many=True)

    class Meta:
        model = models.Todo
        fields = ('title', 'description', 'due_at', 'tags')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...