Django Rest Framework - Фильтр с логическими и

Я использую Django Rest Framework с DjangoFilterBackend для фильтрации публикаций. У каждой публикации может быть несколько авторов. Мой вызов api для фильтрации авторов выглядит следующим образом:

/api/v1/publication/?author=1&author=2

Это дает мне все публикации, к которым был приписан автор 1 или автор 2. Вместо этого я хочу видеть только те публикации, которые опубликовали оба автора. Другими словами, это должна быть логика and, а не or.

Мой код следующий:

models.py

class Publication(models.Model):
    id = models.BigAutoField(primary_key=True)
    title = models.CharField(max_length=400)
    author = models.ManyToManyField(Author, blank=False)
    type = models.ForeignKey(
        Type, on_delete=models.PROTECT, null=False, default=1)
    label = models.ManyToManyField(Label, blank=True)
    date = models.DateField(blank=False, null=False)
    url = models.URLField(null=True, blank=True)
    journal = models.CharField(max_length=400, blank=True)
    bibtex = models.TextField(blank=True)
    public = models.BooleanField(default=False)
    updated = models.DateTimeField(auto_now=True)
    created = models.DateTimeField(auto_now_add=True)
    file = models.FileField(upload_to=upload_path, blank=True, null=True)

    class Meta:
        ordering = ['-date']

    def __str__(self):
        return self.title 

views.py

class PublicationFilter(django_filters.FilterSet):
    author = django_filters.ModelMultipleChoiceFilter(
        queryset=Author.objects.all())

    class Meta:
        model = Publication
        fields = {
            'title': ["exact"],
            'author': ["exact"]
        }


class PublicationView(viewsets.ModelViewSet):
    queryset = Publication.objects.prefetch_related(
        'author', 'label').select_related('type')
    serializer_class = PublicationSerializer
    filter_backends = [DjangoFilterBackend,
                       SearchFilter, OrderingFilter]
    filterset_fields = ['title', 'date', 'journal', 'label', 'author']
    search_fields = ['title']
    ordering_fields = ['date', 'title'] 

serializers.py

class PublicationSerializer(ModelSerializer):
    type = TypeSerializer(read_only=False, many=False)
    label = LabelSerializer(read_only=False, many=True)
    author = AuthorSerializer(read_only=False, many=True)

    class Meta:
        model = Publication
        fields = ['id', 'title', 'date',
                  'url', 'journal',  'label', 'author', 'type', 'date', 'bibtex', 'file']

Я думаю, если вы передадите только одно поле author в url-запросе, но разделите значения запятой, вы получите в итоге список значений в django-фильтре.

/api/v1/publication/?author=1,2

Вы можете переопределить метод filter_author в своем классе PublicationFilter и построить фильтр запросов вручную.

См. здесь под method: https://django-filter.readthedocs.io/en/stable/ref/filters.html#method

Вы можете построить запрос с помощью объекта Q: Как динамически составить фильтр запроса OR в Django?

Вернуться на верх