mirror of
https://github.com/django/django.git
synced 2025-03-31 19:46:42 +00:00
Merging in master
Signed-off-by: Jason Myers <jason@jasonamyers.com>
This commit is contained in:
commit
4f151da1e5
@ -1,7 +1,11 @@
|
|||||||
from django.db.models.sql.aggregates import Aggregate
|
from django.db.models.sql import aggregates
|
||||||
|
from django.db.models.sql.aggregates import * # NOQA
|
||||||
from django.contrib.gis.db.models.fields import GeometryField
|
from django.contrib.gis.db.models.fields import GeometryField
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ['Collect', 'Extent', 'Extent3D', 'MakeLine', 'Union'] + aggregates.__all__
|
||||||
|
|
||||||
|
|
||||||
class GeoAggregate(Aggregate):
|
class GeoAggregate(Aggregate):
|
||||||
# Default SQL template for spatial aggregates.
|
# Default SQL template for spatial aggregates.
|
||||||
sql_template = '%(function)s(%(field)s)'
|
sql_template = '%(function)s(%(field)s)'
|
||||||
|
@ -5,6 +5,10 @@ import copy
|
|||||||
|
|
||||||
from django.db.models.fields import IntegerField, FloatField
|
from django.db.models.fields import IntegerField, FloatField
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ['Aggregate', 'Avg', 'Count', 'Max', 'Min', 'StdDev', 'Sum', 'Variance']
|
||||||
|
|
||||||
|
|
||||||
# Fake fields used to identify aggregate types in data-conversion operations.
|
# Fake fields used to identify aggregate types in data-conversion operations.
|
||||||
ordinal_aggregate_field = IntegerField()
|
ordinal_aggregate_field = IntegerField()
|
||||||
computed_aggregate_field = FloatField()
|
computed_aggregate_field = FloatField()
|
||||||
|
@ -134,7 +134,11 @@ def model_to_dict(instance, fields=None, exclude=None):
|
|||||||
data[f.name] = []
|
data[f.name] = []
|
||||||
else:
|
else:
|
||||||
# MultipleChoiceWidget needs a list of pks, not object instances.
|
# MultipleChoiceWidget needs a list of pks, not object instances.
|
||||||
data[f.name] = list(f.value_from_object(instance).values_list('pk', flat=True))
|
qs = f.value_from_object(instance)
|
||||||
|
if qs._result_cache is not None:
|
||||||
|
data[f.name] = [item.pk for item in qs]
|
||||||
|
else:
|
||||||
|
data[f.name] = list(qs.values_list('pk', flat=True))
|
||||||
else:
|
else:
|
||||||
data[f.name] = f.value_from_object(instance)
|
data[f.name] = f.value_from_object(instance)
|
||||||
return data
|
return data
|
||||||
|
@ -2,7 +2,12 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from unittest import TestCase
|
from unittest import TestCase, skipIf
|
||||||
|
|
||||||
|
try:
|
||||||
|
import pytz
|
||||||
|
except ImportError:
|
||||||
|
pytz = None
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
@ -641,6 +646,7 @@ class DateTimePickerSeleniumIETests(DateTimePickerSeleniumFirefoxTests):
|
|||||||
webdriver_class = 'selenium.webdriver.ie.webdriver.WebDriver'
|
webdriver_class = 'selenium.webdriver.ie.webdriver.WebDriver'
|
||||||
|
|
||||||
|
|
||||||
|
@skipIf(pytz is None, "this test requires pytz")
|
||||||
@override_settings(TIME_ZONE='Asia/Singapore')
|
@override_settings(TIME_ZONE='Asia/Singapore')
|
||||||
@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
|
@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
|
||||||
class DateTimePickerShortcutsSeleniumFirefoxTests(AdminSeleniumWebDriverTestCase):
|
class DateTimePickerShortcutsSeleniumFirefoxTests(AdminSeleniumWebDriverTestCase):
|
||||||
@ -660,9 +666,18 @@ class DateTimePickerShortcutsSeleniumFirefoxTests(AdminSeleniumWebDriverTestCase
|
|||||||
"""
|
"""
|
||||||
self.admin_login(username='super', password='secret', login_url='/')
|
self.admin_login(username='super', password='secret', login_url='/')
|
||||||
|
|
||||||
now = datetime.now()
|
|
||||||
error_margin = timedelta(seconds=10)
|
error_margin = timedelta(seconds=10)
|
||||||
|
|
||||||
|
# If we are neighbouring a DST, we add an hour of error margin.
|
||||||
|
tz = pytz.timezone('America/Chicago')
|
||||||
|
utc_now = datetime.now(pytz.utc)
|
||||||
|
tz_yesterday = (utc_now - timedelta(days=1)).astimezone(tz).tzname()
|
||||||
|
tz_tomorrow = (utc_now + timedelta(days=1)).astimezone(tz).tzname()
|
||||||
|
if tz_yesterday != tz_tomorrow:
|
||||||
|
error_margin += timedelta(hours=1)
|
||||||
|
|
||||||
|
now = datetime.now()
|
||||||
|
|
||||||
self.selenium.get('%s%s' % (self.live_server_url,
|
self.selenium.get('%s%s' % (self.live_server_url,
|
||||||
'/admin_widgets/member/add/'))
|
'/admin_widgets/member/add/'))
|
||||||
|
|
||||||
|
@ -828,6 +828,41 @@ class ModelToDictTests(TestCase):
|
|||||||
# Ensure many-to-many relation appears as a list
|
# Ensure many-to-many relation appears as a list
|
||||||
self.assertIsInstance(d['categories'], list)
|
self.assertIsInstance(d['categories'], list)
|
||||||
|
|
||||||
|
def test_reuse_prefetched(self):
|
||||||
|
# model_to_dict should not hit the database if it can reuse
|
||||||
|
# the data populated by prefetch_related.
|
||||||
|
categories = [
|
||||||
|
Category(name='TestName1', slug='TestName1', url='url1'),
|
||||||
|
Category(name='TestName2', slug='TestName2', url='url2'),
|
||||||
|
Category(name='TestName3', slug='TestName3', url='url3')
|
||||||
|
]
|
||||||
|
for c in categories:
|
||||||
|
c.save()
|
||||||
|
writer = Writer(name='Test writer')
|
||||||
|
writer.save()
|
||||||
|
|
||||||
|
art = Article(
|
||||||
|
headline='Test article',
|
||||||
|
slug='test-article',
|
||||||
|
pub_date=datetime.date(1988, 1, 4),
|
||||||
|
writer=writer,
|
||||||
|
article='Hello.'
|
||||||
|
)
|
||||||
|
art.save()
|
||||||
|
for c in categories:
|
||||||
|
art.categories.add(c)
|
||||||
|
|
||||||
|
art = Article.objects.prefetch_related('categories').get(pk=art.pk)
|
||||||
|
|
||||||
|
with self.assertNumQueries(0):
|
||||||
|
d = model_to_dict(art)
|
||||||
|
|
||||||
|
#Ensure all many-to-many categories appear in model_to_dict
|
||||||
|
for c in categories:
|
||||||
|
self.assertIn(c.pk, d['categories'])
|
||||||
|
#Ensure many-to-many relation appears as a list
|
||||||
|
self.assertIsInstance(d['categories'], list)
|
||||||
|
|
||||||
|
|
||||||
class OldFormForXTests(TestCase):
|
class OldFormForXTests(TestCase):
|
||||||
def test_base_form(self):
|
def test_base_form(self):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user