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:
@@ -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)),
|
||||
)
|
||||
|
||||
@@ -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"]]
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -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]
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -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>
|
||||
@@ -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)>]
|
||||
|
||||
"""}
|
||||
|
||||
|
||||
@@ -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)),
|
||||
)
|
||||
|
||||
@@ -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
|
||||
"""
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 = ()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user