Упрощение написания коллекции 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