используйте django_filters для фильтрации нескольких аргументов

Я использую Relay, Django, Graphene Graphql.

Я хотел бы использовать django_filters для фильтрации нескольких аргументов типа размещения. Это описано в моем файле схемы, и банкомат выглядит так:

class AccommodationNode(DjangoObjectType) :
    class Meta:
        model = Accommodation
        interfaces = (relay.Node,)
        filter_fields = ['type']

Это прекрасно работает, если я передаю одну строку, например: {"accommodationType": "apartment"}, но что, если я хочу отфильтровать все варианты размещения, которые являются апартаментами ИЛИ отелями? что-то вроде: {"accommodationType": ["apartment","hotel"]}

Это моя модель:

class Accommodation(models.Model):
    ACCOMMODATION_TYPE_CHOICES = (
        ('apartment', 'Apartment'),
        ('host_family', 'Host Family'),
        ('residence', 'Residence'),
    )
    school = models.ForeignKey(School, on_delete=models.CASCADE, related_name='accommodations')
    type = models.CharField(
        max_length=200,
        choices=ACCOMMODATION_TYPE_CHOICES,
        default='apartment'
    )
    def __str__(self):
        return str(self.school) + " - " + self.type

Есть ли способ сделать это без написания пользовательских фильтров, как предлагается здесь ? Только для одного поля фильтра это отличное решение, но в моем приложении будет около 50, включая связанные объекты...


person Joey van Breukelen    schedule 19.12.2017    source источник


Ответы (2)


Взгляните на фильтры Django REST Framework:

https://github.com/philipn/django-rest-framework-filters

Он поддерживает не только точные совпадения, например in, которые вы ищете, но также exact, startswith и многие другие в том же стиле ORM Django. Я часто использую его и был впечатлен — он даже интегрируется с API DRF для просмотра веб-страниц. Удачи!

person FlipperPA    schedule 19.12.2017
comment
Спасибо! Дам немного больше пояснений в ответе сам :) - person Joey van Breukelen; 19.12.2017

как упоминал FlipperPA, мне нужно использовать «in». Согласно документам django_filter:

Поиск «в» возвращает фильтр, полученный из BaseInFilter на основе CSV.

и пример BaseInFilter в документах:

class NumberRangeFilter(BaseInFilter, NumberFilter):
    pass

class F(FilterSet):
    id__range = NumberRangeFilter(name='id', lookup_expr='range')

    class Meta:
        model = User

User.objects.create(username='alex')
User.objects.create(username='jacob')
User.objects.create(username='aaron')
User.objects.create(username='carl')

# Range: User with IDs between 1 and 3.
f = F({'id__range': '1,3'})
assert len(f.qs) == 3

Ответ на мой вопрос:

class AccommodationNode(DjangoObjectType) :
    class Meta:
        model = Accommodation
        interfaces = (relay.Node,)
        filter_fields = {
            'type': ['in']
            }

С аргументом {"accommodationType": "apartment,hotel"} будет работать

person Joey van Breukelen    schedule 19.12.2017