Question

I have a little problem.

I have a model Person and a list: fields=['firstname', 'age'].

Now, I would like to iterate over the fields list and do something like this:

people = Person.objects.all() #this is just to start
people_filtered = people.filter(firstname__icontains='ohn')

I am aware of a method

f = Person._meta.get_field('firstname') 

and that returns me an instance of a field

<django.db.models.fields.CharField: firstname>

but putting it like this:

people.filter(f__icontains='ohn')

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 667, in filter
    return self._filter_or_exclude(False, *args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 685, in _filter_or_exclude
    clone.query.add_q(Q(*args, **kwargs))
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/sql/query.py", line 1259, in add_q
    can_reuse=used_aliases, force_having=force_having)
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/sql/query.py", line 1127, in add_filter
process_extras=process_extras)
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/sql/query.py", line 1325, in setup_joins
    "Choices are: %s" % (name, ", ".join(names)))
FieldError: Cannot resolve keyword 'f' into field. Choices are: age, firstname, id, lastname

How from this field get the result with '__icontains' I am hoping for?

class Person(models.Model):
    firstname = models.CharField(null=False, blank=False, max_length=32)
    lastname = models.CharField(null=False, blank=False, max_length=32)
    age = models.IntegerField(null=False, blank=False, max_length=8)
Was it helpful?

Solution

What list of string are you referring to? List of potential values or list of filters/arguments?

If you want the keywords/filters to be dynamic, then doing something like

key = '%s__icontains' % firstname

people.filter(**{key:'ohn'})

should work

If you want values to be dynamic, then this might work:

values = ['ohn', 'john', 'doe']

people.filter(firstname__icontains__in = values)

Im not sure if you can chain sql functions like icontains and in like that, but perhaps you can. I'm sure we are not first who have thought about this

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top