How to rename (exposed in API) filter field name using django-filters?

那年仲夏 提交于 2021-02-07 06:29:08

问题


As the question states - I'm trying to rename the filter field name exposed in my API.

I have the following models:

class Championship(Model):
    ...

class Group(Model):
    championship = ForeignKey(Championship, ...)

class Match(Model):
    group = ForeignKey(Group, ...)

I have exposed all of these models in REST API. I've defined filter_fields for the Match model:

class MatchViewSet(ModelViewSet):
    filter_fields = ['group__championship']
    ...

This way, I can filter for specific championship's matches (tested and working):

curl /api/matches/?group__championship=1

Is is possible to use some kind of alias for the exposed filter so I can use the following:

curl /api/matches/?championship=1

where championship in this case will be an alias for group__championship?

pip freeze returns:

django-filter==0.15.2
(...)

I've also tried implementing custom FilterSet with ModelChoiceFilter and custom lookup method:

class MatchFilterSet(FilterSet):
    championship = ModelChoiceFilter(method='filter_championship')

    def filter_championship(self, queryset, name, value):
        return queryset.filter(group__championship=value)

    class Meta:
        model = Match
        fields = ['championship']

With view:

class MatchViewSet(ModelViewSet):
    filter = MatchFilterSet
    (...)

But with no luck. The filter_championship method was even never called.


回答1:


You need to provide model field as name in django_filters with field type. I am considering you are trying to filter by championship id.

class MatchFilterSet(FilterSet):
    championship = django_filters.NumberFilter(field_name='group__championship_id')

    class Meta:
        model = Match
        fields = ['championship']



回答2:


After Naresh response I have figured out the source of error.

It was the implementation of the model's view:

class MatchViewSet(ModelViewSet):
    filter = MatchFilterSet
    (...)

For django-filter it should be filter_class rather than filter, so the correct implementation is:

class MatchViewSet(ModelViewSet):
    filter_class = MatchFilterSet
    (...)

Also, I've changed the implementation of the model's filter to be more like Naresh suggested:

class MatchFilterSet(FilterSet):
    championship = NumberFilter(field_name='group__championship')

    class Meta:
        model = Match
        fields = ['championship']

The difference between above and the Naresh's one is the luck of _id part which is not necessary.

After these changes everything works fine.



来源:https://stackoverflow.com/questions/39992515/how-to-rename-exposed-in-api-filter-field-name-using-django-filters

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!