Fixed #5535 -- Allow using an explicit foreign key in get() calls. Thanks, Michal Petrucha.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@16473 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
f54135fa4d
commit
dbffffa7dc
|
@ -1068,8 +1068,9 @@ class Query(object):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
field, target, opts, join_list, last, extra_filters = self.setup_joins(
|
field, target, opts, join_list, last, extra_filters = self.setup_joins(
|
||||||
parts, opts, alias, True, allow_many, can_reuse=can_reuse,
|
parts, opts, alias, True, allow_many, allow_explicit_fk=True,
|
||||||
negate=negate, process_extras=process_extras)
|
can_reuse=can_reuse, negate=negate,
|
||||||
|
process_extras=process_extras)
|
||||||
except MultiJoin, e:
|
except MultiJoin, e:
|
||||||
self.split_exclude(filter_expr, LOOKUP_SEP.join(parts[:e.level]),
|
self.split_exclude(filter_expr, LOOKUP_SEP.join(parts[:e.level]),
|
||||||
can_reuse)
|
can_reuse)
|
||||||
|
|
|
@ -365,6 +365,16 @@ translates (roughly) into the following SQL::
|
||||||
|
|
||||||
.. _`Keyword Arguments`: http://docs.python.org/tutorial/controlflow.html#keyword-arguments
|
.. _`Keyword Arguments`: http://docs.python.org/tutorial/controlflow.html#keyword-arguments
|
||||||
|
|
||||||
|
.. versionchanged:: 1.4
|
||||||
|
|
||||||
|
The field specified in a lookup has to be the name of a model field.
|
||||||
|
There's one exception though, in case of a
|
||||||
|
:class:`~django.db.models.fields.ForeignKey` you can specify the field
|
||||||
|
name suffixed with ``_id``. In this case, the value parameter is expected
|
||||||
|
to contain the raw value of the foreign model's primary key. For example::
|
||||||
|
|
||||||
|
>>> Entry.objects.filter(blog_id__exact=4)
|
||||||
|
|
||||||
If you pass an invalid keyword argument, a lookup function will raise
|
If you pass an invalid keyword argument, a lookup function will raise
|
||||||
``TypeError``.
|
``TypeError``.
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ from copy import deepcopy
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.core.exceptions import FieldError
|
from django.core.exceptions import FieldError, MultipleObjectsReturned
|
||||||
|
|
||||||
from models import Article, Reporter
|
from models import Article, Reporter
|
||||||
|
|
||||||
|
@ -229,10 +229,6 @@ class ManyToOneTests(TestCase):
|
||||||
"<Article: John's second story>",
|
"<Article: John's second story>",
|
||||||
"<Article: This is a test>",
|
"<Article: This is a test>",
|
||||||
])
|
])
|
||||||
# You need two underscores between "reporter" and "id" -- not one.
|
|
||||||
self.assertRaises(FieldError, Article.objects.filter, reporter_id__exact=self.r.id)
|
|
||||||
# You need to specify a comparison clause
|
|
||||||
self.assertRaises(FieldError, Article.objects.filter, reporter_id=self.r.id)
|
|
||||||
|
|
||||||
def test_reverse_selects(self):
|
def test_reverse_selects(self):
|
||||||
a3 = Article.objects.create(id=None, headline="Third article",
|
a3 = Article.objects.create(id=None, headline="Third article",
|
||||||
|
@ -372,3 +368,34 @@ class ManyToOneTests(TestCase):
|
||||||
# recursive don't cause recursion depth problems under deepcopy.
|
# recursive don't cause recursion depth problems under deepcopy.
|
||||||
self.r.cached_query = Article.objects.filter(reporter=self.r)
|
self.r.cached_query = Article.objects.filter(reporter=self.r)
|
||||||
self.assertEqual(repr(deepcopy(self.r)), "<Reporter: John Smith>")
|
self.assertEqual(repr(deepcopy(self.r)), "<Reporter: John Smith>")
|
||||||
|
|
||||||
|
def test_explicit_fk(self):
|
||||||
|
# Create a new Article with get_or_create using an explicit value
|
||||||
|
# for a ForeignKey.
|
||||||
|
a2, created = Article.objects.get_or_create(id=None,
|
||||||
|
headline="John's second test",
|
||||||
|
pub_date=datetime(2011, 5, 7),
|
||||||
|
reporter_id=self.r.id)
|
||||||
|
self.assertTrue(created)
|
||||||
|
self.assertEqual(a2.reporter.id, self.r.id)
|
||||||
|
|
||||||
|
# You can specify filters containing the explicit FK value.
|
||||||
|
self.assertQuerysetEqual(
|
||||||
|
Article.objects.filter(reporter_id__exact=self.r.id),
|
||||||
|
[
|
||||||
|
"<Article: John's second test>",
|
||||||
|
"<Article: This is a test>",
|
||||||
|
])
|
||||||
|
|
||||||
|
# Create an Article by Paul for the same date.
|
||||||
|
a3 = Article.objects.create(id=None, headline="Paul's commentary",
|
||||||
|
pub_date=datetime(2011, 5, 7),
|
||||||
|
reporter_id=self.r2.id)
|
||||||
|
self.assertEqual(a3.reporter.id, self.r2.id)
|
||||||
|
|
||||||
|
# Get should respect explicit foreign keys as well.
|
||||||
|
self.assertRaises(MultipleObjectsReturned,
|
||||||
|
Article.objects.get, reporter_id=self.r.id)
|
||||||
|
self.assertEqual(repr(a3),
|
||||||
|
repr(Article.objects.get(reporter_id=self.r2.id,
|
||||||
|
pub_date=datetime(2011, 5, 7))))
|
||||||
|
|
Loading…
Reference in New Issue