filtres complexes ne sont pas hors de la boîte supportée par DRF ou même par plug-in django-filtre. Pour les cas simples, vous pouvez définir votre propre méthode de get_queryset
Ceci est directement à partir de la documentation
def get_queryset(self):
queryset = Purchase.objects.all()
username = self.request.query_params.get('username', None)
if username is not None:
queryset = queryset.filter(purchaser__username=username)
return queryset
Cependant, cela peut rapidement devenir malpropre si vous êtes pris en charge plusieurs filtres et même certains d'entre eux complexe.
La solution consiste à définir une classe filterBackend personnalisée et un ViewSet Mixin. Ce mélange indique au viewet comment comprendre un backend de filtre typique et ce backend peut comprendre des filtres très complexes, tous explicitement définis, y compris des règles quand ces filtres doivent être appliqués.
Une base de filtre échantillon est comme ça (je l'ai défini trois filtres différents sur différents paramètres de la requête dans l'ordre croissant de complexité.
class SomeFiltersBackend(FiltersBackendBase):
"""
Filter backend class to compliment GenericFilterMixin from utils/mixin.
"""
mapping = {'owner': 'filter_by_owner',
'catness': 'filter_by_catness',
'context': 'filter_by_context'}
def rule(self):
return resolve(self.request.path_info).url_name == 'pet-owners-list'
filtre avant tout droit lookups ORM
def filter_by_catness(self, value):
"""
A simple filter to display owners of pets with high catness, canines excuse.
"""
catness = self.request.query_params.get('catness')
return Q(owner__pet__catness__gt=catness)
def filter_by_owner(self, value):
if value == 'me':
return Q(owner=self.request.user.profile)
elif value.isdigit():
try:
profile = PetOwnerProfile.objects.get(user__id=value)
except PetOwnerProfile.DoesNotExist:
raise ValidationError('Owner does not exist')
return Q(owner=profile)
else:
raise ValidationError('Wrong filter applied with owner')
Filtres plus complexes:
def filter_by_context(self, value):
"""
value = {"context_type" : "context_id or context_ids separated by comma"}
"""
import json
try:
context = json.loads(value)
except json.JSONDecodeError as e:
raise ValidationError(e)
context_type, context_ids = context.items()
context_ids = [int(i) for i in context_ids]
if context_type == 'default':
ids = context_ids
else:
ids = Context.get_ids_by_unsupported_contexts(context_type, context_ids)
else:
raise ValidationError('Wrong context type found')
return Q(context_id__in=ids)
Pour comprendre pleinement comment IS, il fonctionne, vous pouvez lire mon blogpost détaillée: http://iank.it/pluggable-filters-for-django-rest-framework/
Tout le code est là dans un Gist ainsi: https://gist.github.com/ankitml/fc8f4cf30ff40e19eae6
Mais qu'en est multiple partie comme property_type = maison, maison – Harry
Je veux avoir tous dans la requête, de sorte que chaque subburb ou quel que soit le filtre est. – Harry
Ok je l'ai, comme ce Foo.objects.filter (name__in = ["Ceci", "That", "Ceux"]) – Harry