Упрощение написания коллекции if/else в запросах Django

У меня есть код в Django views.py, который выглядит следующим образом:

if query_type == 'list':

    if column == 'person':
        person_qs = Person.objects.filter(name__in = query_items_set)

    elif column == 'grandparent':
        person_qs = Person.objects.filter(grandparent__name__in = query_items_set)

    elif column == 'child':
        person_qs = Person.objects.filter(child__name__in = query_items_set)

elif query_type == 'regex':

    if column == 'person':
        person_qs = Person.objects.filter(name__regex = regex_query)

    elif column == 'grandparent':
        person_qs = Person.objects.filter(grandparent__name__regex = regex_query)

    elif column == 'child':
        person_qs = Person.objects.filter(child__name__regex = regex_query)

Когда дело доходит до написания представлений, есть ли более общепринятый/конкретный способ избежать повторений, сохраняя при этом читабельность и расширяемость? Или файлы views.py обычно выглядят так? Или более распространены таблицы диспетчеризации?

Для подобных случаев DRF (Django REST Framework) является распространенным и очень полезным решением. Здесь приведена документация о фильтрации.

Пример.

Вид:

from myapp.models import Person
from myapp.serializers import PersonSerializer
from rest_framework import generics

class PersonList(generics.ListAPIView):
    serializer_class = PersonSerializer
    filter_backends = [
        SearchFilter
    ]
    search_fields = [
        'name', 'grandparent__name', 'child__name',  # For substring search
        '$name', '$grandparent__name', '$child__name'  # For regex search
    ]

Вам также понадобится Serializer:

class PersonSerializer(serializers.ModelSerializer):
    class Meta:
        model = Person
        fields = '__all__'

Вот и все.

Спасибо всем, кто предложил django-filter.

> pip install django-filter

settings.py

INSTALLED_APPS = [
    ...
    'django_filters',
]

views.py

class PersonFilter(django_filters.FilterSet):
    class Meta:
        model = Person
        fields = {'name': ['exact', 'regex'], 
                  'child__name': ['exact', 'regex'], 
                  'grandparent__name': ['exact', 'regex']}

        ...

        person_qs = PersonFilter(request.GET, queryset = Person.objects.all().qs
Вернуться на верх