1

I want to dynamically add the filter field conditionally if a search phrase exists in a custom action viewset. Is there a way to do it. I tried the following but i get SyntaxError: keyword can't be an expression

field = req_serializer.validated_data['field']
search = req_serializer.validated_data['search']

qs = self.get_queryset()
if search:
    qs.filter(field + '__icontains='=search)
pikk
  • 837
  • 5
  • 21
  • 38
  • Don't forget to assign the output of `.filter()` if you plan on using the result; normaly I assign it to override the old `qs` variable like this `qs = qs.filter(...)` – Ralf Jan 22 '21 at 13:27

1 Answers1

1

You can build a dict and then unpack it through standard python double asterisks (This answer talks a bit more about the unpacking of dicts).

params = {
    '{}__icontains'.format(field): search,
}
qs = qs.filter(**params)

This way is specially useful if you want to conditionally add many filter values and unpack them only once in the .filter() statement.

qs = self.get_queryset()
filter_params = {}

for field_name in ['field_1', 'field_2']:
    field_value = req_serializer.validated_data[field_name]

    if field_value:
        k = '{}__icontains'.format(field_name)
        filter_params[k] = field_value   # adds a new key to the dict

if len(filter_params) > 0:
    qs = qs.filter(**filter_params)
Ralf
  • 16,086
  • 4
  • 44
  • 68