1

I am writing a function that can return table items based on a dynamically inserted model. So I need to refrain from using the model name in the function. Now I sometimes will have a many-to-many relationship with another model and want to select on that.

Say I have a projects = ManyToMany(Projects) field in my Files model. Now I can use:

filter(projects__in=[1])

to select for files related to projects with id 1, but I need the projects part of this filter to be dynamic, so I can use something like:

a_field = 'projects'
filter(a_field+'__in'=[1])

which obviously doesn't work. How should I do this?

Niels
  • 537
  • 5
  • 22

1 Answers1

4

You can do this by using the **kwargs in Python: you construct a dictionary that maps string (the name of the parameters), to values, and then call the function with a dictionary with two asterisks, like:

a_field = 'projects'
params = {a_field+'__in': [1]}
filter(**params)

we of course need to construct the dictionary on a separate line:

a_field = 'projects'
filter(**{a_field+'__in': [1]})

If you thus have a dictionary like {'foo': 'bar', 'qux': 14}, then calling it with foo(**{'foo': 'bar', 'qux': 14}) is equivalent to foo(foo='bar', qux=14). This technique is not specific towards Django, but to Python. Python also has a way to do this with positional parameters: foo(*[1, 'a', 4]) is equivalent to foo(1, 'a', 4).

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555