I'm writing a web application (DRF + Vue.js) where frontend should have an ability to narrow down GET request results via different filters.
For example, I have a model like this:
class Human(models.Model):
first_name = models.CharField(_('first name'), max_length=50, null=True, blank=True)
last_name = models.CharField(_('last name'), max_length=50, null=True, blank=True)
birth_date = models.DateField(_('birth date'), blank=True, null=True)
city = models.ForeignKey('City', on_delete=models.SET_NULL, blank=True, null=True)
phone_number = models.ForeignKey('Contact' on_delete=models.SET_NULL, blank=True, null=True)
@property
def full_name(self):
# Last name + First name
return ' '.join(str(x) for x in (self.last_name, self.first_name) if x)
@property
def is_adult(self):
now = timezone.now()
if self.birth_date:
if now.year - self.birth_date.year - \
((now.month, now.day) < (self.birth_date.month, self.birth_date.day)) >= 18:
return True
return False
Now I have simple CRUD ViewSet where I can use a list of search_fields
to search by all needed fields (in my case that's birth_date
, city
, phone_number
and full_name
/is_adult
). But here next problems arise:
- Using
search_fields
I can do a search only by all fields specified in the ViewSet'ssearch_fields
(frontend can't search only bycity
or other distinct fields if it wants to) - other way I'll need to create a separate ViewSet (and separate URL?) for every combination of fields to filter by. Terrific.
So it looks like the correct decision must be capable of filtering by several GET parameters at once. Ideally - with opportunity to chooseexact
/icontains
/etc comparison method on each query.
That sounds like a work for django-filter but I'm not sure yet. - It's impossible to search/filter by
full_name
oris_adult
because they are dynamic model properties, not usual fields.
So it looks like instead of using model properties I need to use separate QuerySets (Manager methods?) that will do the logic of fiddling with model fields and creating the filtered result.
But for now I didn't find a way to choose different QuerySets in a single ViewSet depending on GET parameters (or how to use search by these complex properties together with simple search from problem 1?).
And I have no understanding if it is possible to provide this kind of search by the same URL as a "simple" search - likesite.com/api/people/?city=^New&full_name=John%20Doe
(perfectly - with opportunity to document query parameters for OpenAPI schema / Swagger)
So maybe someone knows which is the most elegant way to provide a capability of such complex search with Django/DRF? In which direction should I look?