Предположим, у нас есть следующие модели:
from django.db import models
class Foo(models.Model):
name = models.CharField(max_length=50)
class Bar(models.Model):
name = models.CharField(max_length=50)
class Zomg(models.Model):
foo = models.ForeignKey(Foo)
bar = models.ForeignKey(Bar)
В Zomg
поля модели foo
и bar
служат составным ключом, то есть для любой пары (foo
, bar
) есть только один Zomg
объект.
В моем проекте мне нужно время от времени обновлять тысячи Zomg
записей, поэтому эффективность поиска записей важна.Проблема в том, что я не могу просто передать foo_id
и bar_id
методу Zomg.objects.get()
:
>>> z = models.Zomg.objects.get(foo_id=1, bar_id=1)
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/lib/python2.7/site-packages/django/db/models/manager.py", line 132, in get
return self.get_query_set().get(*args, **kwargs)
File "/usr/lib/python2.7/site-packages/django/db/models/query.py", line 341, in get
clone = self.filter(*args, **kwargs)
File "/usr/lib/python2.7/site-packages/django/db/models/query.py", line 550, in filter
return self._filter_or_exclude(False, *args, **kwargs)
File "/usr/lib/python2.7/site-packages/django/db/models/query.py", line 568, in _filter_or_exclude
clone.query.add_q(Q(*args, **kwargs))
File "/usr/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1194, in add_q
can_reuse=used_aliases, force_having=force_having)
File "/usr/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1069, in add_filter
negate=negate, process_extras=process_extras)
File "/usr/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1260, in setup_joins
"Choices are: %s" % (name, ", ".join(names)))
FieldError: Cannot resolve keyword 'foo_id' into field. Choices are: bar, foo, id
Однако, когда создается экземпляр объекта, foo_id
и bar_id
в значительной степени доступны:
>>> z.foo_id
1
>>> z.bar_id
1
Теперь я вынужден сначала получить объекты Foo
и Bar
, а затем использовать их для получения необходимого объекта Zomg
, делая два ненужных запроса к базе данных:
>>> f = models.Foo.objects.get(id=1)
>>> b = models.Bar.objects.get(id=1)
>>> z = models.Zomg.objects.get(foo=f, bar=b)
Итак, вопрос в том, как я могу получить Zomg
объект по идентификаторам связанных полей?