Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Merging in master

Signed-off-by: Jason Myers <jason@jasonamyers.com>
  • Loading branch information...
commit 4f151da1e5e9bf527548a5737d9cd314e3abc68e 2 parents 6f07027 + f40f90d
Jason Myers authored November 03, 2013
6  django/contrib/gis/db/models/sql/aggregates.py
... ...
@@ -1,7 +1,11 @@
1  
-from django.db.models.sql.aggregates import Aggregate
  1
+from django.db.models.sql import aggregates
  2
+from django.db.models.sql.aggregates import *  # NOQA
2 3
 from django.contrib.gis.db.models.fields import GeometryField
3 4
 
4 5
 
  6
+__all__ = ['Collect', 'Extent', 'Extent3D', 'MakeLine', 'Union'] + aggregates.__all__
  7
+
  8
+
5 9
 class GeoAggregate(Aggregate):
6 10
     # Default SQL template for spatial aggregates.
7 11
     sql_template = '%(function)s(%(field)s)'
4  django/db/models/sql/aggregates.py
@@ -5,6 +5,10 @@
5 5
 
6 6
 from django.db.models.fields import IntegerField, FloatField
7 7
 
  8
+
  9
+__all__ = ['Aggregate', 'Avg', 'Count', 'Max', 'Min', 'StdDev', 'Sum', 'Variance']
  10
+
  11
+
8 12
 # Fake fields used to identify aggregate types in data-conversion operations.
9 13
 ordinal_aggregate_field = IntegerField()
10 14
 computed_aggregate_field = FloatField()
6  django/forms/models.py
@@ -134,7 +134,11 @@ def model_to_dict(instance, fields=None, exclude=None):
134 134
                 data[f.name] = []
135 135
             else:
136 136
                 # MultipleChoiceWidget needs a list of pks, not object instances.
137  
-                data[f.name] = list(f.value_from_object(instance).values_list('pk', flat=True))
  137
+                qs = f.value_from_object(instance)
  138
+                if qs._result_cache is not None:
  139
+                    data[f.name] = [item.pk for item in qs]
  140
+                else:
  141
+                    data[f.name] = list(qs.values_list('pk', flat=True))
138 142
         else:
139 143
             data[f.name] = f.value_from_object(instance)
140 144
     return data
19  tests/admin_widgets/tests.py
@@ -2,7 +2,12 @@
2 2
 from __future__ import unicode_literals
3 3
 
4 4
 from datetime import datetime, timedelta
5  
-from unittest import TestCase
  5
+from unittest import TestCase, skipIf
  6
+
  7
+try:
  8
+    import pytz
  9
+except ImportError:
  10
+    pytz = None
6 11
 
7 12
 from django import forms
8 13
 from django.conf import settings
@@ -641,6 +646,7 @@ class DateTimePickerSeleniumIETests(DateTimePickerSeleniumFirefoxTests):
641 646
     webdriver_class = 'selenium.webdriver.ie.webdriver.WebDriver'
642 647
 
643 648
 
  649
+@skipIf(pytz is None, "this test requires pytz")
644 650
 @override_settings(TIME_ZONE='Asia/Singapore')
645 651
 @override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
646 652
 class DateTimePickerShortcutsSeleniumFirefoxTests(AdminSeleniumWebDriverTestCase):
@@ -660,9 +666,18 @@ def test_date_time_picker_shortcuts(self):
660 666
         """
661 667
         self.admin_login(username='super', password='secret', login_url='/')
662 668
 
663  
-        now = datetime.now()
664 669
         error_margin = timedelta(seconds=10)
665 670
 
  671
+        # If we are neighbouring a DST, we add an hour of error margin.
  672
+        tz = pytz.timezone('America/Chicago')
  673
+        utc_now = datetime.now(pytz.utc)
  674
+        tz_yesterday = (utc_now - timedelta(days=1)).astimezone(tz).tzname()
  675
+        tz_tomorrow = (utc_now + timedelta(days=1)).astimezone(tz).tzname()
  676
+        if tz_yesterday != tz_tomorrow:
  677
+            error_margin += timedelta(hours=1)
  678
+
  679
+        now = datetime.now()
  680
+
666 681
         self.selenium.get('%s%s' % (self.live_server_url,
667 682
             '/admin_widgets/member/add/'))
668 683
 
35  tests/model_forms/tests.py
@@ -828,6 +828,41 @@ def test_model_to_dict_many_to_many(self):
828 828
         # Ensure many-to-many relation appears as a list
829 829
         self.assertIsInstance(d['categories'], list)
830 830
 
  831
+    def test_reuse_prefetched(self):
  832
+        # model_to_dict should not hit the database if it can reuse
  833
+        # the data populated by prefetch_related.
  834
+        categories = [
  835
+            Category(name='TestName1', slug='TestName1', url='url1'),
  836
+            Category(name='TestName2', slug='TestName2', url='url2'),
  837
+            Category(name='TestName3', slug='TestName3', url='url3')
  838
+        ]
  839
+        for c in categories:
  840
+            c.save()
  841
+        writer = Writer(name='Test writer')
  842
+        writer.save()
  843
+
  844
+        art = Article(
  845
+            headline='Test article',
  846
+            slug='test-article',
  847
+            pub_date=datetime.date(1988, 1, 4),
  848
+            writer=writer,
  849
+            article='Hello.'
  850
+        )
  851
+        art.save()
  852
+        for c in categories:
  853
+            art.categories.add(c)
  854
+
  855
+        art = Article.objects.prefetch_related('categories').get(pk=art.pk)
  856
+
  857
+        with self.assertNumQueries(0):
  858
+            d = model_to_dict(art)
  859
+
  860
+        #Ensure all many-to-many categories appear in model_to_dict
  861
+        for c in categories:
  862
+            self.assertIn(c.pk, d['categories'])
  863
+        #Ensure many-to-many relation appears as a list
  864
+        self.assertIsInstance(d['categories'], list)
  865
+
831 866
 
832 867
 class OldFormForXTests(TestCase):
833 868
     def test_base_form(self):

0 notes on commit 4f151da

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