Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #5535 -- Allow using an explicit foreign key in get() calls. Th…

…anks, Michal Petrucha.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16473 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit dbffffa7dc95fc62cbecfd00284bde62ee796f48 1 parent f54135f
Jannis Leidel authored June 28, 2011
5  django/db/models/sql/query.py
@@ -1068,8 +1068,9 @@ def add_filter(self, filter_expr, connector=AND, negate=False, trim=False,
1068 1068
 
1069 1069
         try:
1070 1070
             field, target, opts, join_list, last, extra_filters = self.setup_joins(
1071  
-                    parts, opts, alias, True, allow_many, can_reuse=can_reuse,
1072  
-                    negate=negate, process_extras=process_extras)
  1071
+                    parts, opts, alias, True, allow_many, allow_explicit_fk=True,
  1072
+                    can_reuse=can_reuse, negate=negate,
  1073
+                    process_extras=process_extras)
1073 1074
         except MultiJoin, e:
1074 1075
             self.split_exclude(filter_expr, LOOKUP_SEP.join(parts[:e.level]),
1075 1076
                     can_reuse)
10  docs/topics/db/queries.txt
@@ -365,6 +365,16 @@ translates (roughly) into the following SQL::
365 365
 
366 366
    .. _`Keyword Arguments`: http://docs.python.org/tutorial/controlflow.html#keyword-arguments
367 367
 
  368
+.. versionchanged:: 1.4
  369
+
  370
+    The field specified in a lookup has to be the name of a model field.
  371
+    There's one exception though, in case of a
  372
+    :class:`~django.db.models.fields.ForeignKey` you can specify the field
  373
+    name suffixed with ``_id``. In this case, the value parameter is expected
  374
+    to contain the raw value of the foreign model's primary key. For example::
  375
+
  376
+        >>> Entry.objects.filter(blog_id__exact=4)
  377
+
368 378
 If you pass an invalid keyword argument, a lookup function will raise
369 379
 ``TypeError``.
370 380
 
37  tests/modeltests/many_to_one/tests.py
@@ -2,7 +2,7 @@
2 2
 from datetime import datetime
3 3
 
4 4
 from django.test import TestCase
5  
-from django.core.exceptions import FieldError
  5
+from django.core.exceptions import FieldError, MultipleObjectsReturned
6 6
 
7 7
 from models import Article, Reporter
8 8
 
@@ -229,10 +229,6 @@ def test_selects(self):
229 229
                 "<Article: John's second story>",
230 230
                 "<Article: This is a test>",
231 231
             ])
232  
-        # You need two underscores between "reporter" and "id" -- not one.
233  
-        self.assertRaises(FieldError, Article.objects.filter, reporter_id__exact=self.r.id)
234  
-        # You need to specify a comparison clause
235  
-        self.assertRaises(FieldError, Article.objects.filter, reporter_id=self.r.id)
236 232
 
237 233
     def test_reverse_selects(self):
238 234
         a3 = Article.objects.create(id=None, headline="Third article",
@@ -372,3 +368,34 @@ def test_regression_12876(self):
372 368
         # recursive don't cause recursion depth problems under deepcopy.
373 369
         self.r.cached_query = Article.objects.filter(reporter=self.r)
374 370
         self.assertEqual(repr(deepcopy(self.r)), "<Reporter: John Smith>")
  371
+
  372
+    def test_explicit_fk(self):
  373
+        # Create a new Article with get_or_create using an explicit value
  374
+        # for a ForeignKey.
  375
+        a2, created = Article.objects.get_or_create(id=None,
  376
+                                                    headline="John's second test",
  377
+                                                    pub_date=datetime(2011, 5, 7),
  378
+                                                    reporter_id=self.r.id)
  379
+        self.assertTrue(created)
  380
+        self.assertEqual(a2.reporter.id, self.r.id)
  381
+
  382
+        # You can specify filters containing the explicit FK value.
  383
+        self.assertQuerysetEqual(
  384
+            Article.objects.filter(reporter_id__exact=self.r.id),
  385
+            [
  386
+                "<Article: John's second test>",
  387
+                "<Article: This is a test>",
  388
+            ])
  389
+
  390
+        # Create an Article by Paul for the same date.
  391
+        a3 = Article.objects.create(id=None, headline="Paul's commentary",
  392
+                                    pub_date=datetime(2011, 5, 7),
  393
+                                    reporter_id=self.r2.id)
  394
+        self.assertEqual(a3.reporter.id, self.r2.id)
  395
+
  396
+        # Get should respect explicit foreign keys as well.
  397
+        self.assertRaises(MultipleObjectsReturned,
  398
+                          Article.objects.get, reporter_id=self.r.id)
  399
+        self.assertEqual(repr(a3),
  400
+                         repr(Article.objects.get(reporter_id=self.r2.id,
  401
+                                             pub_date=datetime(2011, 5, 7))))

0 notes on commit dbffffa

Please sign in to comment.
Something went wrong with that request. Please try again.