Reputation: 1524
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?
Upvotes: 7
Views: 13485
Reputation: 1650
JPG answer is right, but if you got lots of fields and relations it will be tedious work. But you can actually declare relations in field
meta:
class ArticleFilter(django_filters.rest_framework.FilterSet):
class Meta:
model = Article
fields = ['article', 'writer__name']
Or with lookup expressions:
class ArticleFilter(django_filters.rest_framework.FilterSet):
class Meta:
model = Article
fields = {
'article': ('exact', ),
'relationship__name': ('exact', 'contains')
}
And even more optimization:
def prefix_dict_keys(prefix: str, d: dict):
return {prefix + k: v for k, v in d.items()}
class ArticleFilter(django_filters.rest_framework.FilterSet):
class Meta:
model = Article
fields = {
'article': ('exact', ),
...
**prefix_dict_keys('writer__'
{
'name': ('exact', 'contains')),
...
}),
...
}
Upvotes: 5
Reputation: 88539
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
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']
Upvotes: 12
Reputation: 1458
You can try like this. My class custom your filter with new param. Your api must have extra param . In this case is ?article_name='example'
class WriteFilter(django_filters.rest_framework.FilterSet):
class Meta:
model = WriterFilter
fields = ['article_name']
article_name = ArticleFilter(name="article_name")
class ArticleFilter(django_filters.Filter):
def filter(self, qs, value):
return qs.article_set.filter(name=value)
If you run queryset, it will get all Writer with article name is 'example'.
Hoop this help
Upvotes: 2