Author: jezdez
Date: 2011-06-28 03:16:18 -0700 (Tue, 28 Jun 2011)
New Revision: 16473

Modified:
   django/trunk/django/db/models/sql/query.py
   django/trunk/docs/topics/db/queries.txt
   django/trunk/tests/modeltests/many_to_one/tests.py
Log:
Fixed #5535 -- Allow using an explicit foreign key in get() calls. Thanks, 
Michal Petrucha.

Modified: django/trunk/django/db/models/sql/query.py
===================================================================
--- django/trunk/django/db/models/sql/query.py  2011-06-28 04:29:48 UTC (rev 
16472)
+++ django/trunk/django/db/models/sql/query.py  2011-06-28 10:16:18 UTC (rev 
16473)
@@ -1068,8 +1068,9 @@
 
         try:
             field, target, opts, join_list, last, extra_filters = 
self.setup_joins(
-                    parts, opts, alias, True, allow_many, can_reuse=can_reuse,
-                    negate=negate, process_extras=process_extras)
+                    parts, opts, alias, True, allow_many, 
allow_explicit_fk=True,
+                    can_reuse=can_reuse, negate=negate,
+                    process_extras=process_extras)
         except MultiJoin, e:
             self.split_exclude(filter_expr, LOOKUP_SEP.join(parts[:e.level]),
                     can_reuse)

Modified: django/trunk/docs/topics/db/queries.txt
===================================================================
--- django/trunk/docs/topics/db/queries.txt     2011-06-28 04:29:48 UTC (rev 
16472)
+++ django/trunk/docs/topics/db/queries.txt     2011-06-28 10:16:18 UTC (rev 
16473)
@@ -365,6 +365,16 @@
 
    .. _`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
 ``TypeError``.
 

Modified: django/trunk/tests/modeltests/many_to_one/tests.py
===================================================================
--- django/trunk/tests/modeltests/many_to_one/tests.py  2011-06-28 04:29:48 UTC 
(rev 16472)
+++ django/trunk/tests/modeltests/many_to_one/tests.py  2011-06-28 10:16:18 UTC 
(rev 16473)
@@ -2,7 +2,7 @@
 from datetime import datetime
 
 from django.test import TestCase
-from django.core.exceptions import FieldError
+from django.core.exceptions import FieldError, MultipleObjectsReturned
 
 from models import Article, Reporter
 
@@ -229,10 +229,6 @@
                 "<Article: John's second story>",
                 "<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):
         a3 = Article.objects.create(id=None, headline="Third article",
@@ -372,3 +368,34 @@
         # recursive don't cause recursion depth problems under deepcopy.
         self.r.cached_query = Article.objects.filter(reporter=self.r)
         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))))

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to django-updates@googlegroups.com.
To unsubscribe from this group, send email to 
django-updates+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to