Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django-filter filter by related fields

I have two tables.

class Writer(models.Model)
    name = model.CharField()
    ...

class Article(models.Model)
    name = model.CharField()
    writer = model.ForeignKey('Writer', related_name="relationship") 
    ...

I wanted to build some API endpoints getting the writer list, but this should be filterable by Article id. I am using django-filter. So:

class WriterViewSet(viewsets.ReadOnlyModelViewSet):
   filter_backend = [filters.djangoFilterBackend],
   filter_class = WriterFilter


class WriteFilter(django_filters.rest_framework.FilterSet):
....

So my concern is, how can I define WriteFilter to filter Writer by the article?

like image 389
Snipper03 Avatar asked Jul 22 '18 18:07

Snipper03


People also ask

How do you query a many to many relationship in Django?

When querying many-to-many relationships, avoid using multiple filter() methods, make use of Q() objects instead. You can check the SQL query of a QuerySet with str(queryset. query) . Check the performance of recently executed SQL queries with django.

What is a QuerySet?

A QuerySet represents a collection of objects from your database. It can have zero, one or many filters. Filters narrow down the query results based on the given parameters. In SQL terms, a QuerySet equates to a SELECT statement, and a filter is a limiting clause such as WHERE or LIMIT .

What is __ in Django ORM?

Django Field Lookups Managers and QuerySet objects comes with a feature called lookups. A lookup is composed of a model field followed by two underscores ( __ ) which is then followed by lookup name.


1 Answers

class WriteFilter(django_filters.rest_framework.FilterSet):
    article = django_filters.CharFilter(name='relationship__name', lookup_expr='contains')

    class Meta:
        model = WriterFilter
        fields = ['article']


Your url will be like this,
/api/wtiter/list/?article=somearticlename


UPDATE-1

since django-filter 2.0, the name argument changed to field_name.

Hence the filter class will be,

class WriteFilter(django_filters.rest_framework.FilterSet):
    article = django_filters.CharFilter(field_name='relationship__name', lookup_expr='contains')

    class Meta:
        model = WriterFilter
        fields = ['article']
like image 131
JPG Avatar answered Sep 18 '22 03:09

JPG