0

I'm using Django Rest Framework with DjangoFilterBackend to filter through Publications. Every publication can have multiple authors. My api call to filter the api for authors looks like:

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

This gives me every publication that either author 1 or author 2 has been assigned to. Instead I want to only see the publications that both have published. In other words it should be a logic and, not or.

My code is the following:

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']
Matthias
  • 15
  • 3

1 Answers1

0

I think if you will pass only one author field in the url query, but separate the values with a comma you will end up with a list value in the django-filter.

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

Than you can override filter_author method in your PublicationFilter class and build the query filter manually there.

See here under method: https://django-filter.readthedocs.io/en/stable/ref/filters.html#method

You can build the query with a help of the Q object: How to dynamically compose an OR query filter in Django?