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?