I have code in a Django views.py
that looks like:
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)
When it comes to writing views, is there a more accepted/concise way of avoiding repitition, while still maintaining readability and extensibility? Or do views.py
files tend to look like this? Or are dispatch tables more common?
CodePudding user response:
For cases like this DRF (Django REST Framework) is a common and very useful solution. Here are the docs about filtering.
An example.
View:
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
]
And you will also need a Serializer
:
class PersonSerializer(serializers.ModelSerializer):
class Meta:
model = Person
fields = '__all__'
That's all.
CodePudding user response:
Thanks to everyone who suggested 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