1
0
mirror of https://github.com/django/django.git synced 2025-10-24 14:16:09 +00:00

[soc2009/multidb] Merged up to trunk r11864.

git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/multidb@11866 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Alex Gaynor
2009-12-14 17:47:04 +00:00
parent 2794cceb5f
commit 4e25ca00c8
45 changed files with 1598 additions and 240 deletions

View File

@@ -3,5 +3,5 @@ from django.conf.urls.defaults import *
import widgetadmin
urlpatterns = patterns('',
(r'^deep/down/admin/(.*)', widgetadmin.site.root),
(r'^deep/down/admin/', include(widgetadmin.site.urls)),
)

View File

@@ -0,0 +1,32 @@
[
{
"pk": "4",
"model": "fixtures_regress.person",
"fields": {
"name": "Neal Stephenson"
}
},
{
"pk": "2",
"model": "fixtures_regress.store",
"fields": {
"name": "Amazon"
}
},
{
"pk": "3",
"model": "fixtures_regress.store",
"fields": {
"name": "Borders"
}
},
{
"pk": 1,
"model": "fixtures_regress.book",
"fields": {
"name": "Cryptonomicon",
"author": ["Neal Stephenson"],
"stores": [["Amazon"], ["Borders"]]
}
}
]

View File

@@ -0,0 +1,25 @@
[
{
"pk": 12,
"model": "fixtures_regress.person",
"fields": {
"name": "Greg Egan"
}
},
{
"pk": 11,
"model": "fixtures_regress.store",
"fields": {
"name": "Angus and Robertson"
}
},
{
"pk": 10,
"model": "fixtures_regress.book",
"fields": {
"name": "Permutation City",
"author": 12,
"stores": [11]
}
}
]

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<django-objects version="1.0">
<object pk="22" model="fixtures_regress.person">
<field type="CharField" name="name">Orson Scott Card</field>
</object>
<object pk="21" model="fixtures_regress.store">
<field type="CharField" name="name">Collins Bookstore</field>
</object>
<object pk="20" model="fixtures_regress.book">
<field type="CharField" name="name">Ender's Game</field>
<field to="fixtures_regress.person" name="author" rel="ManyToOneRel">22</field>
<field to="fixtures_regress.store" name="stores" rel="ManyToManyRel">
<object pk="21"/>
</field>
</object>
</django-objects>

View File

@@ -13,7 +13,7 @@ class Animal(models.Model):
specimens = models.Manager()
def __unicode__(self):
return self.common_name
return self.name
def animal_pre_save_check(signal, sender, instance, **kwargs):
"A signal that is used to check the type of data loaded from fixtures"
@@ -70,10 +70,66 @@ class Article(models.Model):
class Widget(models.Model):
name = models.CharField(max_length=255)
class Meta:
ordering = ('name',)
def __unicode__(self):
return self.name
class WidgetProxy(Widget):
class Meta:
proxy = True
# Check for forward references in FKs and M2Ms with natural keys
class TestManager(models.Manager):
def get_by_natural_key(self, key):
return self.get(name=key)
class Store(models.Model):
objects = TestManager()
name = models.CharField(max_length=255)
class Meta:
ordering = ('name',)
def __unicode__(self):
return self.name
def natural_key(self):
return (self.name,)
class Person(models.Model):
objects = TestManager()
name = models.CharField(max_length=255)
class Meta:
ordering = ('name',)
def __unicode__(self):
return self.name
# Person doesn't actually have a dependency on store, but we need to define
# one to test the behaviour of the dependency resolution algorithm.
def natural_key(self):
return (self.name,)
natural_key.dependencies = ['fixtures_regress.store']
class Book(models.Model):
name = models.CharField(max_length=255)
author = models.ForeignKey(Person)
stores = models.ManyToManyField(Store)
class Meta:
ordering = ('name',)
def __unicode__(self):
return u'%s by %s (available at %s)' % (
self.name,
self.author.name,
', '.join(s.name for s in self.stores.all())
)
__test__ = {'API_TESTS':"""
>>> from django.core import management
@@ -193,4 +249,121 @@ Weight = 1.2 (<type 'float'>)
>>> management.call_command('dumpdata', 'fixtures_regress', format='json')
[{"pk": 1, "model": "fixtures_regress.widget", "fields": {"name": "grommet"}}]
###############################################
# Check that natural key requirements are taken into account
# when serializing models
>>> management.call_command('loaddata', 'forward_ref_lookup.json', verbosity=0)
>>> management.call_command('dumpdata', 'fixtures_regress.book', 'fixtures_regress.person', 'fixtures_regress.store', verbosity=0, use_natural_keys=True)
[{"pk": 2, "model": "fixtures_regress.store", "fields": {"name": "Amazon"}}, {"pk": 3, "model": "fixtures_regress.store", "fields": {"name": "Borders"}}, {"pk": 4, "model": "fixtures_regress.person", "fields": {"name": "Neal Stephenson"}}, {"pk": 1, "model": "fixtures_regress.book", "fields": {"stores": [["Amazon"], ["Borders"]], "name": "Cryptonomicon", "author": ["Neal Stephenson"]}}]
# Now lets check the dependency sorting explicitly
# First Some models with pathological circular dependencies
>>> class Circle1(models.Model):
... name = models.CharField(max_length=255)
... def natural_key(self):
... return self.name
... natural_key.dependencies = ['fixtures_regress.circle2']
>>> class Circle2(models.Model):
... name = models.CharField(max_length=255)
... def natural_key(self):
... return self.name
... natural_key.dependencies = ['fixtures_regress.circle1']
>>> class Circle3(models.Model):
... name = models.CharField(max_length=255)
... def natural_key(self):
... return self.name
... natural_key.dependencies = ['fixtures_regress.circle3']
>>> class Circle4(models.Model):
... name = models.CharField(max_length=255)
... def natural_key(self):
... return self.name
... natural_key.dependencies = ['fixtures_regress.circle5']
>>> class Circle5(models.Model):
... name = models.CharField(max_length=255)
... def natural_key(self):
... return self.name
... natural_key.dependencies = ['fixtures_regress.circle6']
>>> class Circle6(models.Model):
... name = models.CharField(max_length=255)
... def natural_key(self):
... return self.name
... natural_key.dependencies = ['fixtures_regress.circle4']
>>> class ExternalDependency(models.Model):
... name = models.CharField(max_length=255)
... def natural_key(self):
... return self.name
... natural_key.dependencies = ['fixtures_regress.book']
# It doesn't matter what order you mention the models
# Store *must* be serialized before then Person, and both
# must be serialized before Book.
>>> from django.core.management.commands.dumpdata import sort_dependencies
>>> sort_dependencies([('fixtures_regress', [Book, Person, Store])])
[<class 'regressiontests.fixtures_regress.models.Store'>, <class 'regressiontests.fixtures_regress.models.Person'>, <class 'regressiontests.fixtures_regress.models.Book'>]
>>> sort_dependencies([('fixtures_regress', [Book, Store, Person])])
[<class 'regressiontests.fixtures_regress.models.Store'>, <class 'regressiontests.fixtures_regress.models.Person'>, <class 'regressiontests.fixtures_regress.models.Book'>]
>>> sort_dependencies([('fixtures_regress', [Store, Book, Person])])
[<class 'regressiontests.fixtures_regress.models.Store'>, <class 'regressiontests.fixtures_regress.models.Person'>, <class 'regressiontests.fixtures_regress.models.Book'>]
>>> sort_dependencies([('fixtures_regress', [Store, Person, Book])])
[<class 'regressiontests.fixtures_regress.models.Store'>, <class 'regressiontests.fixtures_regress.models.Person'>, <class 'regressiontests.fixtures_regress.models.Book'>]
>>> sort_dependencies([('fixtures_regress', [Person, Book, Store])])
[<class 'regressiontests.fixtures_regress.models.Store'>, <class 'regressiontests.fixtures_regress.models.Person'>, <class 'regressiontests.fixtures_regress.models.Book'>]
>>> sort_dependencies([('fixtures_regress', [Person, Store, Book])])
[<class 'regressiontests.fixtures_regress.models.Store'>, <class 'regressiontests.fixtures_regress.models.Person'>, <class 'regressiontests.fixtures_regress.models.Book'>]
# A dangling dependency - assume the user knows what they are doing.
>>> sort_dependencies([('fixtures_regress', [Person, Circle1, Store, Book])])
[<class 'regressiontests.fixtures_regress.models.Circle1'>, <class 'regressiontests.fixtures_regress.models.Store'>, <class 'regressiontests.fixtures_regress.models.Person'>, <class 'regressiontests.fixtures_regress.models.Book'>]
# A tight circular dependency
>>> sort_dependencies([('fixtures_regress', [Person, Circle2, Circle1, Store, Book])])
Traceback (most recent call last):
...
CommandError: Can't resolve dependencies for fixtures_regress.Circle1, fixtures_regress.Circle2 in serialized app list.
>>> sort_dependencies([('fixtures_regress', [Circle1, Book, Circle2])])
Traceback (most recent call last):
...
CommandError: Can't resolve dependencies for fixtures_regress.Circle1, fixtures_regress.Circle2 in serialized app list.
# A self referential dependency
>>> sort_dependencies([('fixtures_regress', [Book, Circle3])])
Traceback (most recent call last):
...
CommandError: Can't resolve dependencies for fixtures_regress.Circle3 in serialized app list.
# A long circular dependency
>>> sort_dependencies([('fixtures_regress', [Person, Circle2, Circle1, Circle3, Store, Book])])
Traceback (most recent call last):
...
CommandError: Can't resolve dependencies for fixtures_regress.Circle1, fixtures_regress.Circle2, fixtures_regress.Circle3 in serialized app list.
# A dependency on a normal, non-natural-key model
>>> sort_dependencies([('fixtures_regress', [Person, ExternalDependency, Book])])
[<class 'regressiontests.fixtures_regress.models.Person'>, <class 'regressiontests.fixtures_regress.models.Book'>, <class 'regressiontests.fixtures_regress.models.ExternalDependency'>]
###############################################
# Check that normal primary keys still work
# on a model with natural key capabilities
>>> management.call_command('loaddata', 'non_natural_1.json', verbosity=0)
>>> management.call_command('loaddata', 'non_natural_2.xml', verbosity=0)
>>> Book.objects.all()
[<Book: Cryptonomicon by Neal Stephenson (available at Amazon, Borders)>, <Book: Ender's Game by Orson Scott Card (available at Collins Bookstore)>, <Book: Permutation City by Greg Egan (available at Angus and Robertson)>]
"""}

View File

@@ -2,5 +2,5 @@ from django.conf.urls.defaults import *
from django.contrib import admin
urlpatterns = patterns('',
(r'^admin/(.*)', admin.site.root),
(r'^admin/', include(admin.site.urls)),
)

View File

@@ -10,9 +10,13 @@ context_tests = r"""
>>> c['a'] = 2
>>> c['a']
2
>>> c.get('a')
2
>>> c.pop()
{'a': 2}
>>> c['a']
1
>>> c.get('foo', 42)
42
"""

View File

@@ -15,7 +15,7 @@ import unittest
from django import template
from django.core import urlresolvers
from django.template import loader
from django.template.loaders import app_directories, filesystem
from django.template.loaders import app_directories, filesystem, cached
from django.utils.translation import activate, deactivate, ugettext as _
from django.utils.safestring import mark_safe
from django.utils.tzinfo import LocalTimezone
@@ -101,13 +101,15 @@ class UTF8Class:
class Templates(unittest.TestCase):
def test_loaders_security(self):
ad_loader = app_directories.Loader()
fs_loader = filesystem.Loader()
def test_template_sources(path, template_dirs, expected_sources):
if isinstance(expected_sources, list):
# Fix expected sources so they are normcased and abspathed
expected_sources = [os.path.normcase(os.path.abspath(s)) for s in expected_sources]
# Test the two loaders (app_directores and filesystem).
func1 = lambda p, t: list(app_directories.get_template_sources(p, t))
func2 = lambda p, t: list(filesystem.get_template_sources(p, t))
func1 = lambda p, t: list(ad_loader.get_template_sources(p, t))
func2 = lambda p, t: list(fs_loader.get_template_sources(p, t))
for func in (func1, func2):
if isinstance(expected_sources, list):
self.assertEqual(func(path, template_dirs), expected_sources)
@@ -198,8 +200,11 @@ class Templates(unittest.TestCase):
except KeyError:
raise template.TemplateDoesNotExist, template_name
cache_loader = cached.Loader(('test_template_loader',))
cache_loader._cached_loaders = (test_template_loader,)
old_template_loaders = loader.template_source_loaders
loader.template_source_loaders = [test_template_loader]
loader.template_source_loaders = [cache_loader]
failures = []
tests = template_tests.items()
@@ -232,20 +237,22 @@ class Templates(unittest.TestCase):
for invalid_str, result in [('', normal_string_result),
(expected_invalid_str, invalid_string_result)]:
settings.TEMPLATE_STRING_IF_INVALID = invalid_str
try:
test_template = loader.get_template(name)
output = self.render(test_template, vals)
except ContextStackException:
failures.append("Template test (TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Context stack was left imbalanced" % (invalid_str, name))
continue
except Exception:
exc_type, exc_value, exc_tb = sys.exc_info()
if exc_type != result:
tb = '\n'.join(traceback.format_exception(exc_type, exc_value, exc_tb))
failures.append("Template test (TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Got %s, exception: %s\n%s" % (invalid_str, name, exc_type, exc_value, tb))
continue
if output != result:
failures.append("Template test (TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Expected %r, got %r" % (invalid_str, name, result, output))
for is_cached in (False, True):
try:
test_template = loader.get_template(name)
output = self.render(test_template, vals)
except ContextStackException:
failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Context stack was left imbalanced" % (is_cached, invalid_str, name))
continue
except Exception:
exc_type, exc_value, exc_tb = sys.exc_info()
if exc_type != result:
tb = '\n'.join(traceback.format_exception(exc_type, exc_value, exc_tb))
failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Got %s, exception: %s\n%s" % (is_cached, invalid_str, name, exc_type, exc_value, tb))
continue
if output != result:
failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Expected %r, got %r" % (is_cached, invalid_str, name, result, output))
cache_loader.reset()
if 'LANGUAGE_CODE' in vals[1]:
deactivate()

View File

@@ -10,6 +10,7 @@ from django.test.utils import ContextList
from django.core.urlresolvers import reverse
from django.core.exceptions import SuspiciousOperation
from django.template import TemplateDoesNotExist, TemplateSyntaxError, Context
from django.template import loader
class AssertContainsTests(TestCase):
def setUp(self):
@@ -436,6 +437,11 @@ class ExceptionTests(TestCase):
class TemplateExceptionTests(TestCase):
def setUp(self):
# Reset the loaders so they don't try to render cached templates.
if loader.template_source_loaders is not None:
for template_loader in loader.template_source_loaders:
if hasattr(template_loader, 'reset'):
template_loader.reset()
self.old_templates = settings.TEMPLATE_DIRS
settings.TEMPLATE_DIRS = ()