Django-1.6.11/0000775000175000017500000000000012502407547012416 5ustar timtim00000000000000Django-1.6.11/setup.py0000664000175000017500000001072312502407523014125 0ustar timtim00000000000000import os import sys from distutils.core import setup from distutils.sysconfig import get_python_lib # Warn if we are installing over top of an existing installation. This can # cause issues where files that were deleted from a more recent Django are # still present in site-packages. See #18115. overlay_warning = False if "install" in sys.argv: lib_paths = [get_python_lib()] if lib_paths[0].startswith("/usr/lib/"): # We have to try also with an explicit prefix of /usr/local in order to # catch Debian's custom user site-packages directory. lib_paths.append(get_python_lib(prefix="/usr/local")) for lib_path in lib_paths: existing_path = os.path.abspath(os.path.join(lib_path, "django")) if os.path.exists(existing_path): # We note the need for the warning here, but present it after the # command is run, so it's more likely to be seen. overlay_warning = True break def fullsplit(path, result=None): """ Split a pathname into components (the opposite of os.path.join) in a platform-neutral way. """ if result is None: result = [] head, tail = os.path.split(path) if head == '': return [tail] + result if head == path: return result return fullsplit(head, [tail] + result) EXCLUDE_FROM_PACKAGES = ['django.conf.project_template', 'django.conf.app_template', 'django.bin'] def is_package(package_name): for pkg in EXCLUDE_FROM_PACKAGES: if package_name.startswith(pkg): return False return True # Compile the list of packages available, because distutils doesn't have # an easy way to do this. packages, package_data = [], {} root_dir = os.path.dirname(__file__) if root_dir != '': os.chdir(root_dir) django_dir = 'django' for dirpath, dirnames, filenames in os.walk(django_dir): # Ignore PEP 3147 cache dirs and those whose names start with '.' dirnames[:] = [d for d in dirnames if not d.startswith('.') and d != '__pycache__'] parts = fullsplit(dirpath) package_name = '.'.join(parts) if '__init__.py' in filenames and is_package(package_name): packages.append(package_name) elif filenames: relative_path = [] while '.'.join(parts) not in packages: relative_path.append(parts.pop()) relative_path.reverse() path = os.path.join(*relative_path) package_files = package_data.setdefault('.'.join(parts), []) package_files.extend([os.path.join(path, f) for f in filenames]) # Dynamically calculate the version based on django.VERSION. version = __import__('django').get_version() setup( name='Django', version=version, url='http://www.djangoproject.com/', author='Django Software Foundation', author_email='foundation@djangoproject.com', description=('A high-level Python Web framework that encourages ' 'rapid development and clean, pragmatic design.'), license='BSD', packages=packages, package_data=package_data, scripts=['django/bin/django-admin.py'], classifiers=[ 'Development Status :: 5 - Production/Stable', 'Environment :: Web Environment', 'Framework :: Django', 'Intended Audience :: Developers', 'License :: OSI Approved :: BSD License', 'Operating System :: OS Independent', 'Programming Language :: Python', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.2', 'Programming Language :: Python :: 3.3', 'Topic :: Internet :: WWW/HTTP', 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', 'Topic :: Internet :: WWW/HTTP :: WSGI', 'Topic :: Software Development :: Libraries :: Application Frameworks', 'Topic :: Software Development :: Libraries :: Python Modules', ], ) if overlay_warning: sys.stderr.write(""" ======== WARNING! ======== You have just installed Django over top of an existing installation, without removing it first. Because of this, your install may now include extraneous files from a previous version that have since been removed from Django. This is known to cause a variety of problems. You should manually remove the %(existing_path)s directory and re-install Django. """ % {"existing_path": existing_path}) Django-1.6.11/scripts/0000775000175000017500000000000012502407547014105 5ustar timtim00000000000000Django-1.6.11/scripts/rpm-install.sh0000664000175000017500000000145112452634157016707 0ustar timtim00000000000000#! /bin/sh # # This file becomes the install section of the generated spec file. # # This is what dist.py normally does. %{__python} setup.py install --root=${RPM_BUILD_ROOT} --record="INSTALLED_FILES" # Sort the filelist so that directories appear before files. This avoids # duplicate filename problems on some systems. touch DIRS for i in `cat INSTALLED_FILES`; do if [ -f ${RPM_BUILD_ROOT}/$i ]; then echo $i >>FILES fi if [ -d ${RPM_BUILD_ROOT}/$i ]; then echo %dir $i >>DIRS fi done # Make sure we match foo.pyo and foo.pyc along with foo.py (but only once each) sed -e "/\.py[co]$/d" -e "s/\.py$/.py*/" DIRS FILES >INSTALLED_FILES mkdir -p ${RPM_BUILD_ROOT}/%{_mandir}/man1/ cp docs/man/* ${RPM_BUILD_ROOT}/%{_mandir}/man1/ cat << EOF >> INSTALLED_FILES %doc %{_mandir}/man1/*" EOF Django-1.6.11/scripts/manage_translations.py0000664000175000017500000001472112502407523020507 0ustar timtim00000000000000#!/usr/bin/env python # # This python file contains utility scripts to manage Django translations. # It has to be run inside the django git root directory. # # The following commands are available: # # * update_catalogs: check for new strings in core and contrib catalogs, and # output how much strings are new/changed. # # * lang_stats: output statistics for each catalog/language combination # # * fetch: fetch translations from transifex.com # # Each command support the --languages and --resources options to limit their # operation to the specified language or resource. For example, to get stats # for Spanish in contrib.admin, run: # # $ python scripts/manage_translations.py lang_stats --language=es --resources=admin import os from optparse import OptionParser from subprocess import call, Popen, PIPE from django.core.management import call_command HAVE_JS = ['admin'] def _get_locale_dirs(include_core=True): """ Return a tuple (contrib name, absolute path) for all locale directories, optionally including the django core catalog. """ contrib_dir = os.path.join(os.getcwd(), 'django', 'contrib') dirs = [] for contrib_name in os.listdir(contrib_dir): path = os.path.join(contrib_dir, contrib_name, 'locale') if os.path.isdir(path): dirs.append((contrib_name, path)) if contrib_name in HAVE_JS: dirs.append(("%s-js" % contrib_name, path)) if include_core: dirs.insert(0, ('core', os.path.join(os.getcwd(), 'django', 'conf', 'locale'))) return dirs def _tx_resource_for_name(name): """ Return the Transifex resource name """ if name == 'core': return "django.core" else: return "django.contrib-%s" % name def _check_diff(cat_name, base_path): """ Output the approximate number of changed/added strings in the en catalog. """ po_path = '%(path)s/en/LC_MESSAGES/django%(ext)s.po' % { 'path': base_path, 'ext': 'js' if cat_name.endswith('-js') else ''} p = Popen("git diff -U0 %s | egrep -v '^@@|^[-+]#|^..POT-Creation' | wc -l" % po_path, stdout=PIPE, stderr=PIPE, shell=True) output, errors = p.communicate() num_changes = int(output.strip()) - 4 print("%d changed/added messages in '%s' catalog." % (num_changes, cat_name)) def update_catalogs(resources=None, languages=None): """ Update the en/LC_MESSAGES/django.po (main and contrib) files with new/updated translatable strings. """ contrib_dirs = _get_locale_dirs(include_core=False) os.chdir(os.path.join(os.getcwd(), 'django')) print("Updating main en catalog") call_command('makemessages', locale='en') _check_diff('core', os.path.join(os.getcwd(), 'conf', 'locale')) # Contrib catalogs for name, dir_ in contrib_dirs: if resources and not name in resources: continue os.chdir(os.path.join(dir_, '..')) print("Updating en catalog in %s" % dir_) if name.endswith('-js'): call_command('makemessages', locale='en', domain='djangojs') else: call_command('makemessages', locale='en') _check_diff(name, dir_) def lang_stats(resources=None, languages=None): """ Output language statistics of committed translation files for each Django catalog. If resources is provided, it should be a list of translation resource to limit the output (e.g. ['core', 'gis']). """ locale_dirs = _get_locale_dirs() for name, dir_ in locale_dirs: if resources and not name in resources: continue print("\nShowing translations stats for '%s':" % name) langs = sorted([d for d in os.listdir(dir_) if not d.startswith('_')]) for lang in langs: if languages and not lang in languages: continue # TODO: merge first with the latest en catalog p = Popen("msgfmt -vc -o /dev/null %(path)s/%(lang)s/LC_MESSAGES/django%(ext)s.po" % { 'path': dir_, 'lang': lang, 'ext': 'js' if name.endswith('-js') else ''}, stdout=PIPE, stderr=PIPE, shell=True) output, errors = p.communicate() if p.returncode == 0: # msgfmt output stats on stderr print("%s: %s" % (lang, errors.strip())) else: print("Errors happened when checking %s translation for %s:\n%s" % ( lang, name, errors)) def fetch(resources=None, languages=None): """ Fetch translations from Transifex, wrap long lines, generate mo files. """ locale_dirs = _get_locale_dirs() errors = [] for name, dir_ in locale_dirs: if resources and not name in resources: continue # Transifex pull if languages is None: call('tx pull -r %(res)s -a -f' % {'res': _tx_resource_for_name(name)}, shell=True) languages = sorted([d for d in os.listdir(dir_) if not d.startswith('_')]) else: for lang in languages: call('tx pull -r %(res)s -f -l %(lang)s' % { 'res': _tx_resource_for_name(name), 'lang': lang}, shell=True) # msgcat to wrap lines and msgfmt for compilation of .mo file for lang in languages: po_path = '%(path)s/%(lang)s/LC_MESSAGES/django%(ext)s.po' % { 'path': dir_, 'lang': lang, 'ext': 'js' if name.endswith('-js') else ''} call('msgcat -o %s %s' % (po_path, po_path), shell=True) res = call('msgfmt -c -o %s.mo %s' % (po_path[:-3], po_path), shell=True) if res != 0: errors.append((name, lang)) if errors: print("\nWARNING: Errors have occurred in following cases:") for resource, lang in errors: print("\tResource %s for language %s" % (resource, lang)) exit(1) if __name__ == "__main__": RUNABLE_SCRIPTS = ('update_catalogs', 'lang_stats', 'fetch') parser = OptionParser(usage="usage: %prog [options] cmd") parser.add_option("-r", "--resources", action='append', help="limit operation to the specified resources") parser.add_option("-l", "--languages", action='append', help="limit operation to the specified languages") options, args = parser.parse_args() if not args: parser.print_usage() exit(1) if args[0] in RUNABLE_SCRIPTS: eval(args[0])(options.resources, options.languages) else: print("Available commands are: %s" % ", ".join(RUNABLE_SCRIPTS)) Django-1.6.11/MANIFEST.in0000664000175000017500000000310412502407522014143 0ustar timtim00000000000000include README.rst include AUTHORS include INSTALL include LICENSE include MANIFEST.in include django/contrib/gis/gdal/LICENSE include django/contrib/gis/geos/LICENSE include django/dispatch/license.txt recursive-include docs * recursive-include scripts * recursive-include extras * recursive-include tests * recursive-include django/conf/app_template * recursive-include django/conf/locale * recursive-include django/conf/project_template * recursive-include django/contrib/*/locale * recursive-include django/contrib/admin/templates * recursive-include django/contrib/admin/static * recursive-include django/contrib/admindocs/templates * recursive-include django/contrib/auth/fixtures * recursive-include django/contrib/auth/templates * recursive-include django/contrib/auth/tests/templates * recursive-include django/contrib/comments/templates * recursive-include django/contrib/formtools/templates * recursive-include django/contrib/formtools/tests/templates * recursive-include django/contrib/flatpages/fixtures * recursive-include django/contrib/flatpages/tests/templates * recursive-include django/contrib/gis/templates * recursive-include django/contrib/gis/tests/data * recursive-include django/contrib/gis/tests/distapp/fixtures * recursive-include django/contrib/gis/tests/geoapp/fixtures * recursive-include django/contrib/gis/tests/geogapp/fixtures * recursive-include django/contrib/gis/tests/relatedapp/fixtures * recursive-include django/contrib/sitemaps/templates * recursive-include django/contrib/sitemaps/tests/templates * recursive-exclude * __pycache__ recursive-exclude * *.py[co] Django-1.6.11/tests/0000775000175000017500000000000012502407547013560 5ustar timtim00000000000000Django-1.6.11/tests/extra_regress/0000775000175000017500000000000012502407547016435 5ustar timtim00000000000000Django-1.6.11/tests/extra_regress/__init__.py0000664000175000017500000000000012477341424020536 0ustar timtim00000000000000Django-1.6.11/tests/extra_regress/tests.py0000664000175000017500000003361612502407523020154 0ustar timtim00000000000000from __future__ import absolute_import, unicode_literals import datetime from django.contrib.auth.models import User from django.test import TestCase from django.utils.datastructures import SortedDict from .models import TestObject, Order, RevisionableModel class ExtraRegressTests(TestCase): def setUp(self): self.u = User.objects.create_user( username="fred", password="secret", email="fred@example.com" ) def test_regression_7314_7372(self): """ Regression tests for #7314 and #7372 """ rm = RevisionableModel.objects.create( title='First Revision', when=datetime.datetime(2008, 9, 28, 10, 30, 0) ) self.assertEqual(rm.pk, rm.base.pk) rm2 = rm.new_revision() rm2.title = "Second Revision" rm.when = datetime.datetime(2008, 9, 28, 14, 25, 0) rm2.save() self.assertEqual(rm2.title, 'Second Revision') self.assertEqual(rm2.base.title, 'First Revision') self.assertNotEqual(rm2.pk, rm.pk) self.assertEqual(rm2.base.pk, rm.pk) # Queryset to match most recent revision: qs = RevisionableModel.objects.extra( where=["%(table)s.id IN (SELECT MAX(rev.id) FROM %(table)s rev GROUP BY rev.base_id)" % { 'table': RevisionableModel._meta.db_table, }] ) self.assertQuerysetEqual(qs, [('Second Revision', 'First Revision')], transform=lambda r: (r.title, r.base.title) ) # Queryset to search for string in title: qs2 = RevisionableModel.objects.filter(title__contains="Revision") self.assertQuerysetEqual(qs2, [ ('First Revision', 'First Revision'), ('Second Revision', 'First Revision'), ], transform=lambda r: (r.title, r.base.title), ordered=False ) # Following queryset should return the most recent revision: self.assertQuerysetEqual(qs & qs2, [('Second Revision', 'First Revision')], transform=lambda r: (r.title, r.base.title), ordered=False ) def test_extra_stay_tied(self): # Extra select parameters should stay tied to their corresponding # select portions. Applies when portions are updated or otherwise # moved around. qs = User.objects.extra( select=SortedDict((("alpha", "%s"), ("beta", "2"), ("gamma", "%s"))), select_params=(1, 3) ) qs = qs.extra(select={"beta": 4}) qs = qs.extra(select={"alpha": "%s"}, select_params=[5]) self.assertEqual( list(qs.filter(id=self.u.id).values('alpha', 'beta', 'gamma')), [{'alpha': 5, 'beta': 4, 'gamma': 3}] ) def test_regression_7957(self): """ Regression test for #7957: Combining extra() calls should leave the corresponding parameters associated with the right extra() bit. I.e. internal dictionary must remain sorted. """ self.assertEqual( User.objects.extra(select={"alpha": "%s"}, select_params=(1,) ).extra(select={"beta": "%s"}, select_params=(2,))[0].alpha, 1) self.assertEqual( User.objects.extra(select={"beta": "%s"}, select_params=(1,) ).extra(select={"alpha": "%s"}, select_params=(2,))[0].alpha, 2) def test_regression_7961(self): """ Regression test for #7961: When not using a portion of an extra(...) in a query, remove any corresponding parameters from the query as well. """ self.assertEqual( list(User.objects.extra(select={"alpha": "%s"}, select_params=(-6,) ).filter(id=self.u.id).values_list('id', flat=True)), [self.u.id] ) def test_regression_8063(self): """ Regression test for #8063: limiting a query shouldn't discard any extra() bits. """ qs = User.objects.all().extra(where=['id=%s'], params=[self.u.id]) self.assertQuerysetEqual(qs, ['']) self.assertQuerysetEqual(qs[:1], ['']) def test_regression_8039(self): """ Regression test for #8039: Ordering sometimes removed relevant tables from extra(). This test is the critical case: ordering uses a table, but then removes the reference because of an optimisation. The table should still be present because of the extra() call. """ self.assertQuerysetEqual( Order.objects.extra(where=["username=%s"], params=["fred"], tables=["auth_user"] ).order_by('created_by'), [] ) def test_regression_8819(self): """ Regression test for #8819: Fields in the extra(select=...) list should be available to extra(order_by=...). """ self.assertQuerysetEqual( User.objects.filter(pk=self.u.id).extra(select={'extra_field': 1}).distinct(), [''] ) self.assertQuerysetEqual( User.objects.filter(pk=self.u.id).extra(select={'extra_field': 1}, order_by=['extra_field']), [''] ) self.assertQuerysetEqual( User.objects.filter(pk=self.u.id).extra(select={'extra_field': 1}, order_by=['extra_field']).distinct(), [''] ) def test_dates_query(self): """ When calling the dates() method on a queryset with extra selection columns, we can (and should) ignore those columns. They don't change the result and cause incorrect SQL to be produced otherwise. """ rm = RevisionableModel.objects.create( title='First Revision', when=datetime.datetime(2008, 9, 28, 10, 30, 0) ) self.assertQuerysetEqual( RevisionableModel.objects.extra(select={"the_answer": 'id'}).datetimes('when', 'month'), [datetime.datetime(2008, 9, 1, 0, 0)], transform=lambda d: d, ) def test_values_with_extra(self): """ Regression test for #10256... If there is a values() clause, Extra columns are only returned if they are explicitly mentioned. """ obj = TestObject(first='first', second='second', third='third') obj.save() self.assertEqual( list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values()), [{'bar': 'second', 'third': 'third', 'second': 'second', 'whiz': 'third', 'foo': 'first', 'id': obj.pk, 'first': 'first'}] ) # Extra clauses after an empty values clause are still included self.assertEqual( list(TestObject.objects.values().extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third'))))), [{'bar': 'second', 'third': 'third', 'second': 'second', 'whiz': 'third', 'foo': 'first', 'id': obj.pk, 'first': 'first'}] ) # Extra columns are ignored if not mentioned in the values() clause self.assertEqual( list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values('first', 'second')), [{'second': 'second', 'first': 'first'}] ) # Extra columns after a non-empty values() clause are ignored self.assertEqual( list(TestObject.objects.values('first', 'second').extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third'))))), [{'second': 'second', 'first': 'first'}] ) # Extra columns can be partially returned self.assertEqual( list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values('first', 'second', 'foo')), [{'second': 'second', 'foo': 'first', 'first': 'first'}] ) # Also works if only extra columns are included self.assertEqual( list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values('foo', 'whiz')), [{'foo': 'first', 'whiz': 'third'}] ) # Values list works the same way # All columns are returned for an empty values_list() self.assertEqual( list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list()), [('first', 'second', 'third', obj.pk, 'first', 'second', 'third')] ) # Extra columns after an empty values_list() are still included self.assertEqual( list(TestObject.objects.values_list().extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third'))))), [('first', 'second', 'third', obj.pk, 'first', 'second', 'third')] ) # Extra columns ignored completely if not mentioned in values_list() self.assertEqual( list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('first', 'second')), [('first', 'second')] ) # Extra columns after a non-empty values_list() clause are ignored completely self.assertEqual( list(TestObject.objects.values_list('first', 'second').extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third'))))), [('first', 'second')] ) self.assertEqual( list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('second', flat=True)), ['second'] ) # Only the extra columns specified in the values_list() are returned self.assertEqual( list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('first', 'second', 'whiz')), [('first', 'second', 'third')] ) # ...also works if only extra columns are included self.assertEqual( list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('foo','whiz')), [('first', 'third')] ) self.assertEqual( list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('whiz', flat=True)), ['third'] ) # ... and values are returned in the order they are specified self.assertEqual( list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('whiz','foo')), [('third', 'first')] ) self.assertEqual( list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('first','id')), [('first', obj.pk)] ) self.assertEqual( list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('whiz', 'first', 'bar', 'id')), [('third', 'first', 'second', obj.pk)] ) def test_regression_10847(self): """ Regression for #10847: the list of extra columns can always be accurately evaluated. Using an inner query ensures that as_sql() is producing correct output without requiring full evaluation and execution of the inner query. """ obj = TestObject(first='first', second='second', third='third') obj.save() self.assertEqual( list(TestObject.objects.extra(select={'extra': 1}).values('pk')), [{'pk': obj.pk}] ) self.assertQuerysetEqual( TestObject.objects.filter( pk__in=TestObject.objects.extra(select={'extra': 1}).values('pk') ), [''] ) self.assertEqual( list(TestObject.objects.values('pk').extra(select={'extra': 1})), [{'pk': obj.pk}] ) self.assertQuerysetEqual( TestObject.objects.filter( pk__in=TestObject.objects.values('pk').extra(select={'extra': 1}) ), [''] ) self.assertQuerysetEqual( TestObject.objects.filter(pk=obj.pk) | TestObject.objects.extra(where=["id > %s"], params=[obj.pk]), [''] ) def test_regression_17877(self): """ Ensure that extra WHERE clauses get correctly ANDed, even when they contain OR operations. """ # Test Case 1: should appear in queryset. t = TestObject(first='a', second='a', third='a') t.save() # Test Case 2: should appear in queryset. t = TestObject(first='b', second='a', third='a') t.save() # Test Case 3: should not appear in queryset, bug case. t = TestObject(first='a', second='a', third='b') t.save() # Test Case 4: should not appear in queryset. t = TestObject(first='b', second='a', third='b') t.save() # Test Case 5: should not appear in queryset. t = TestObject(first='b', second='b', third='a') t.save() # Test Case 6: should not appear in queryset, bug case. t = TestObject(first='a', second='b', third='b') t.save() self.assertQuerysetEqual( TestObject.objects.extra( where=["first = 'a' OR second = 'a'", "third = 'a'"], ), ['', ''], ordered=False ) Django-1.6.11/tests/extra_regress/models.py0000664000175000017500000000252512502407523020270 0ustar timtim00000000000000from __future__ import unicode_literals import copy import datetime from django.contrib.auth.models import User from django.db import models from django.utils.encoding import python_2_unicode_compatible @python_2_unicode_compatible class RevisionableModel(models.Model): base = models.ForeignKey('self', null=True) title = models.CharField(blank=True, max_length=255) when = models.DateTimeField(default=datetime.datetime.now) def __str__(self): return "%s (%s, %s)" % (self.title, self.id, self.base.id) def save(self, *args, **kwargs): super(RevisionableModel, self).save(*args, **kwargs) if not self.base: self.base = self kwargs.pop('force_insert', None) kwargs.pop('force_update', None) super(RevisionableModel, self).save(*args, **kwargs) def new_revision(self): new_revision = copy.copy(self) new_revision.pk = None return new_revision class Order(models.Model): created_by = models.ForeignKey(User) text = models.TextField() @python_2_unicode_compatible class TestObject(models.Model): first = models.CharField(max_length=20) second = models.CharField(max_length=20) third = models.CharField(max_length=20) def __str__(self): return 'TestObject: %s,%s,%s' % (self.first,self.second,self.third) Django-1.6.11/tests/files/0000775000175000017500000000000012502407547014662 5ustar timtim00000000000000Django-1.6.11/tests/files/__init__.py0000664000175000017500000000000112502407523016754 0ustar timtim00000000000000 Django-1.6.11/tests/files/tests.py0000664000175000017500000001674212502407523016402 0ustar timtim00000000000000from __future__ import absolute_import from io import BytesIO import os import gzip import shutil import tempfile from django.core.cache import cache from django.core.files import File from django.core.files.move import file_move_safe from django.core.files.base import ContentFile from django.core.files.uploadedfile import SimpleUploadedFile from django.core.files.temp import NamedTemporaryFile from django.test import TestCase from django.utils import six, unittest from django.utils.six import StringIO from .models import Storage, temp_storage, temp_storage_location FILE_SUFFIX_REGEX = '[A-Za-z0-9]{7}' class FileStorageTests(TestCase): def tearDown(self): shutil.rmtree(temp_storage_location) def test_files(self): temp_storage.save('tests/default.txt', ContentFile('default content')) # Attempting to access a FileField from the class raises a descriptive # error self.assertRaises(AttributeError, lambda: Storage.normal) # An object without a file has limited functionality. obj1 = Storage() self.assertEqual(obj1.normal.name, "") self.assertRaises(ValueError, lambda: obj1.normal.size) # Saving a file enables full functionality. obj1.normal.save("django_test.txt", ContentFile("content")) self.assertEqual(obj1.normal.name, "tests/django_test.txt") self.assertEqual(obj1.normal.size, 7) self.assertEqual(obj1.normal.read(), b"content") obj1.normal.close() # File objects can be assigned to FileField attributes, but shouldn't # get committed until the model it's attached to is saved. obj1.normal = SimpleUploadedFile("assignment.txt", b"content") dirs, files = temp_storage.listdir("tests") self.assertEqual(dirs, []) self.assertEqual(sorted(files), ["default.txt", "django_test.txt"]) obj1.save() dirs, files = temp_storage.listdir("tests") self.assertEqual( sorted(files), ["assignment.txt", "default.txt", "django_test.txt"] ) # Files can be read in a little at a time, if necessary. obj1.normal.open() self.assertEqual(obj1.normal.read(3), b"con") self.assertEqual(obj1.normal.read(), b"tent") self.assertEqual(list(obj1.normal.chunks(chunk_size=2)), [b"co", b"nt", b"en", b"t"]) obj1.normal.close() # Save another file with the same name. obj2 = Storage() obj2.normal.save("django_test.txt", ContentFile("more content")) obj2_name = obj2.normal.name six.assertRegex(self, obj2_name, "tests/django_test_%s.txt" % FILE_SUFFIX_REGEX) self.assertEqual(obj2.normal.size, 12) # Push the objects into the cache to make sure they pickle properly cache.set("obj1", obj1) cache.set("obj2", obj2) six.assertRegex(self, cache.get("obj2").normal.name, "tests/django_test_%s.txt" % FILE_SUFFIX_REGEX) # Deleting an object does not delete the file it uses. obj2.delete() obj2.normal.save("django_test.txt", ContentFile("more content")) self.assertNotEqual(obj2_name, obj2.normal.name) six.assertRegex(self, obj2.normal.name, "tests/django_test_%s.txt" % FILE_SUFFIX_REGEX) # Multiple files with the same name get _N appended to them. objs = [Storage() for i in range(2)] for o in objs: o.normal.save("multiple_files.txt", ContentFile("Same Content")) names = [o.normal.name for o in objs] self.assertEqual(names[0], "tests/multiple_files.txt") six.assertRegex(self, names[1], "tests/multiple_files_%s.txt" % FILE_SUFFIX_REGEX) for o in objs: o.delete() # Default values allow an object to access a single file. obj3 = Storage.objects.create() self.assertEqual(obj3.default.name, "tests/default.txt") self.assertEqual(obj3.default.read(), b"default content") obj3.default.close() # But it shouldn't be deleted, even if there are no more objects using # it. obj3.delete() obj3 = Storage() self.assertEqual(obj3.default.read(), b"default content") obj3.default.close() # Verify the fix for #5655, making sure the directory is only # determined once. obj4 = Storage() obj4.random.save("random_file", ContentFile("random content")) self.assertTrue(obj4.random.name.endswith("/random_file")) def test_file_object(self): # Create sample file temp_storage.save('tests/example.txt', ContentFile('some content')) # Load it as python file object with open(temp_storage.path('tests/example.txt')) as file_obj: # Save it using storage and read its content temp_storage.save('tests/file_obj', file_obj) self.assertTrue(temp_storage.exists('tests/file_obj')) with temp_storage.open('tests/file_obj') as f: self.assertEqual(f.read(), b'some content') def test_stringio(self): # Test passing StringIO instance as content argument to save output = StringIO() output.write('content') output.seek(0) # Save it and read written file temp_storage.save('tests/stringio', output) self.assertTrue(temp_storage.exists('tests/stringio')) with temp_storage.open('tests/stringio') as f: self.assertEqual(f.read(), b'content') class FileTests(unittest.TestCase): def test_context_manager(self): orig_file = tempfile.TemporaryFile() base_file = File(orig_file) with base_file as f: self.assertIs(base_file, f) self.assertFalse(f.closed) self.assertTrue(f.closed) self.assertTrue(orig_file.closed) def test_namedtemporaryfile_closes(self): """ The symbol django.core.files.NamedTemporaryFile is assigned as a different class on different operating systems. In any case, the result should minimally mock some of the API of tempfile.NamedTemporaryFile from the Python standard library. """ tempfile = NamedTemporaryFile() self.assertTrue(hasattr(tempfile, "closed")) self.assertFalse(tempfile.closed) tempfile.close() self.assertTrue(tempfile.closed) def test_file_mode(self): # Should not set mode to None if it is not present. # See #14681, stdlib gzip module crashes if mode is set to None file = SimpleUploadedFile("mode_test.txt", b"content") self.assertFalse(hasattr(file, 'mode')) g = gzip.GzipFile(fileobj=file) def test_file_iteration(self): """ File objects should yield lines when iterated over. Refs #22107. """ file = File(BytesIO(b'one\ntwo\nthree')) self.assertEqual(list(file), [b'one\n', b'two\n', b'three']) class FileMoveSafeTests(unittest.TestCase): def test_file_move_overwrite(self): handle_a, self.file_a = tempfile.mkstemp(dir=os.environ['DJANGO_TEST_TEMP_DIR']) handle_b, self.file_b = tempfile.mkstemp(dir=os.environ['DJANGO_TEST_TEMP_DIR']) # file_move_safe should raise an IOError exception if destination file exists and allow_overwrite is False self.assertRaises(IOError, lambda: file_move_safe(self.file_a, self.file_b, allow_overwrite=False)) # should allow it and continue on if allow_overwrite is True self.assertIsNone(file_move_safe(self.file_a, self.file_b, allow_overwrite=True)) os.close(handle_a) os.close(handle_b) Django-1.6.11/tests/files/models.py0000664000175000017500000000201612502407523016510 0ustar timtim00000000000000""" 42. Storing files according to a custom storage system ``FileField`` and its variations can take a ``storage`` argument to specify how and where files should be stored. """ import random import tempfile from django.db import models from django.core.files.storage import FileSystemStorage temp_storage_location = tempfile.mkdtemp() temp_storage = FileSystemStorage(location=temp_storage_location) class Storage(models.Model): def custom_upload_to(self, filename): return 'foo' def random_upload_to(self, filename): # This returns a different result each time, # to make sure it only gets called once. return '%s/%s' % (random.randint(100, 999), filename) normal = models.FileField(storage=temp_storage, upload_to='tests') custom = models.FileField(storage=temp_storage, upload_to=custom_upload_to) random = models.FileField(storage=temp_storage, upload_to=random_upload_to) default = models.FileField(storage=temp_storage, upload_to='tests', default='tests/default.txt') Django-1.6.11/tests/file_storage/0000775000175000017500000000000012502407547016223 5ustar timtim00000000000000Django-1.6.11/tests/file_storage/test.png0000664000175000017500000000074212502407523017705 0ustar timtim00000000000000PNG  IHDRh6 pHYs  tIME  ' IDATxڕK(Dqƿsw(YXXLl Q"Ăe$k MIʂW ;c.qsC}cC [9,—jLLDgG-K-gs-Xx7GF&I:$)4W,kG%@8-u5򤸄1v fEUזn|wM%@td%gPo,nHp|q{!%7?\-ͬz;{^vέ^ rPj80պtS)pzuaJ|Q^trpy=. EUhoi`m3lh+sȒ~ry}ޯՠxHYIENDB`Django-1.6.11/tests/file_storage/urls.py0000664000175000017500000000025112502406330017545 0ustar timtim00000000000000from django.conf.urls import patterns, url from django.http import HttpResponse urlpatterns = patterns('', url(r'^$', lambda req: HttpResponse('example view')), ) Django-1.6.11/tests/file_storage/__init__.py0000664000175000017500000000000112502407523020315 0ustar timtim00000000000000 Django-1.6.11/tests/file_storage/magic.png0000664000175000017500000021145512502407523020013 0ustar timtim00000000000000PNG  IHDR (lzTXtsome random textxHs1YS&R5sNw\HW. yd;=x.8>%4([}#WƵɊ9Y3?2ՒU`@DZ,U-LEy@l0ZI !$>p ť&hW:ƵjLn0nꑰOQ`fjstV!穉Җl>)pi.>Fof0ߢ~?`O,!ź& ~Q)OS"u("UY@`ь$ =Cn"W=b;zCQ)+*.IzlT΃jF-'NyM~j3ٟlx{mAXCC>q6FG0 <Iȋ0pf4Bxx)7kw LAa4 AVh"˄W\0B޸B>äPRU'l\ s>)ްR 6[V$w,1Z-&G϶Yv w38og/]5Ҟï߿džVqtsn|vG$Gd XKI%d1"1$yʰ*>*~0`hF@aEQc;Bapst{rze!^߯J V$OH + z<כ]5WwAdzǤVfJb;P̓(Sc*DxWͭ~mC9]N9{m.{@Iҕʡw!YklNK欟vy^#kmXPk {O^= jrSDBϡ[e܅U5w&\i¹8lm~vrKbOG͖ex<}gs='a52;T:Β& Ml9$2vDz~% R6*9C;#5`.ZeѬK&#D94Kh(Yc]"_~dec5"o8Ib-:R3Rd RSIWbd?f1λu6N@"~KdӃ=&'RZ SSUK;W%+C8XqeP&S|\|W&{r"5BUl{^S~ >L, N[̪Eʦ)bmB5C|RPثp&r{jO%duf #edf;qyYjSvrX3od+ǚ?ܶ^Kg*n$[@{A6;;6qkmfux$/*w+ɂ%eM B38)CbqfTک#m+JUPWRލ*R{OdfپAr_iy)r<y\|4&&y6 - :H[l-YH{ڒ'LF.Na{4D-c^}v ͈87i靧Kj{QTcUrC+eA/LUw؊^8vZ;c͛( \xqn*:hf>64](*Ԯu9T֦Um:aְL9c¸j/t{ '2s>5n$$ad"#N[qU% WԿ+4r>e#ykKwFrMuUkw;'P -LS&E/Qu*@؆`9AXOӊN! L,̄aLgsNs%ݸdCs1M^'W3ͫ|" $Q3!\ &毁|g#sd8·4 gʜ1= W'2|~tZ=E?K6*"m/̷$^"3vC$;ͼ}4P76QO?xwiN EW1Aso?qvks>*kpZHÃuş$-Պ0 qW|C Ljb7qa-Akj)j}t͟qX"I>vʺ? >YsS}jMW)}#= ^,>[D\Q/@8$J_w!.OM@6FA( ԆE%?rLM\8 3"u_ fAϟm{j=hI7 u\РXl*ȩvF&EHw_ɊtPAOL/I4&cI`fsSxngATY2B>պGc%)QCVKWl}`>svBzeVH $| Һ:³H]:Le!C: x _wtoD6Xx39/UP/'?LSbȈ.X;zg#{/ xn P2 gg^v 7TܳEe}t7ܾN&dOi\ьIR)t]/Ȫݣ"GwZGڊx%_kw˵">L֥E3GG?i{x/傐a>k=l"eԏ~BzIh6Y7dKrt+Ѽ%U䳟3t[];jp09?نI Owxx.`/Gt\2Q"C /17e ;Ob;jPOv] 0s`]Qg%04{\ȶ8\>Tv;`h0pY9od.:pt?B,>:Bp—S*Ni׮sA>sf_[\jxADhԻCeN.\ޥ+\} 8DPʮiޗ+RD]9뻇=#E0סy69}S·Z/;Tho"Yٍ/ 翌ҫX@V.uӥ8X4ـg iW试,J!(N_7օ(ǨZ:r fYzQ$嬴~(יNvҧ+#)NHB'dz-)W0}`s\EpǑ/~Qop[Z 3ETgLpkiOO؏B3:Wd(9a>zT(\|߷|f~꙯a0D+|l8MjzSJ?@WߟJzv wㅍ\9o:Sj qKPMģzqg`a.bKSv/ijc-0Zp,ȁ\_aTˡTH3Gf:+yk]z_݈+B+هʷva<`: [8.!l[GV`=TyIaG;2f}> ?en\Ǝ aY jdUM"Sߥ~  PKm3>rCs_I ɷaV&6/e$!Ϯ/n;F( 3ȄFj`ߟ;['4`d3&Ԗ'm7!O]3=*we.Hue*5ڋB$z6̀Ku`vPNC3ΑdKqMT {ǩ˩%V+ܾx>#bE}wcjd*Y̘5$4~t}*ܒ{g]oy?eU&`{feΛI{3bDSb$Կ;q?BDc%>> gpB'}6KfK;*3$ʖ1rY|. Geer;d{5nZ?ðRH5(\H2Snh=洘^P#F" qRsb+'g2U n K hllP\wg?@$V-xܰ+s >}pd^p%˄`ի\1ZAՙ:O Hy1Bln%; \2;BәHpӊ)+'T} ̔"| 4F 3WaKºTCHbXz^MYaN>h|H~6W+#оגwH&-pry57^Ie1[X9R75ʔ2؇7/rΤ'+gZ 2t'q$EiҀ#ŴOd֐5uYBkX6M+{রŽdJ)wm7bjb7m2yD۽gv]Ayl ъ>L!):sp_L-ﯢcɒQg@rC/?E*Oץ+[{ϼfm.7Uxt?5LiAt;f\::t wsng׏+;ggT~<{YK=~|,bMh0 Tm_#?egLuKuKJM{UA{ .Z̑YGJW+fYQr[3;s / =6 | /'NLC5S{Tk:Q>Pڎ c^5lC}]yc׷HQ[P9[zZ@99Y ]"G+9u W"`BfQ~pWbpdr Eu>IJElP)T1plo<+|PSW.ԌZvF;hf }eV}pD ʹ \qZF"ᅹSv/J &\5k,.EUMVuD}qjҵKYmc:x`kjvO/U`,C>'_xEgJxD~#?~me1^rPDm]%*gByw"SL>x (w.hѕ;,v氓mL!Unvlz+L؊['ը/[5o0MǎLE*M/ ~WCja#^l'؄jרU+g?@:#흢]oS '7ld%AڶZ/?9L<0ټ/&M0 \~Np +g9l> s@$Tr F1LT1~ ʭvdتЙ¥=_K9tsLhcT0oqe?6n[9gc)tݶǤM#IkBba en 8g&Hh)TGNT^>Y (s B'N:SbD!‡0?, 0P<(n:;N]"O;[wj;0rd3@!c^ȑ:~dX>yoA5A@*+% rRtbL!~mh9v֘F\I͓ ;^_D*!:VY/f%=٘>jX#Ӑq ^' ]&IIWfsFŠT=T%m_P_(t{^stYa)Ӈs Cow jBؾ ?+auNe0.{;])UȢ\ }4\ LiƣWI-+L rWXs #e2~К(%O?gh+&='QX>4('Bre"Xi J3X̷)zԻlю^I?_ϸi<F~ʯ! qP˝6C$ RzA"z[J/GTt_o4D$*_!8Jx9OGUvHPH$N>o߮O"xKONzVIhk?=šyN˾ycy/TCm>ϿF15+^0C)[X Ae|be; 2B&@NcH!EQlbh0tAFs!öb1ٝkЋߏFq燨o$'(֟{&P3d x }a8O Cb-zz2w #iEEDƂ:/S)l`xMP}3i /T1M@;I;=ѰwZG17me/Ԭ 1{_A`8I~~/Otdb)}2#9 $RC`563gEŸ<>)J"1:S2\SmGOLTϤS6PB^.nRwpFɘ[EhA WR£w,# xQb*9 ޮ蠩zdjzxS>9Rqj 5y&'iH\Sj:"A:yr}P9AX~Uٞ|&9"!=!p q ~H\ԍXQjW-;Cm m3D[݁?avŧ=ꓟDx3\V|զ?FQ ,Xf& {'GeQb+bZc:*tДeXgڟ'޲*UȞ"6O e2Z8M|:33->I~i]{v-4n!ЕrP"*Fxz =ZыpGٵu&7:e*}ZLA)]_*|~OSd߷")R WtSGDgz}w9zdYS_yQ+ efGoA͓HzU6CfTK,1!rq#x-./P,8hkdd=̶GhQ-T,u[C_NϞ-dzx;6(_px>CukA&嶹!OV)9,M[OaiWhYaЉ+`o(A%~#;U `tk\ fߓǑ#^;wFv=/;:t QFyP>+gv\bޮ[,2Lў ő)^ p,=|6| Ž%FS,`O fPQ6M]UXcJeq"$Cu$Vdf(ԫC8q*?3`n5_p_gC8Ϩ^_"Rkc_irdt\/SMQIw09UW/,VC|2|]?~:";ƫG ҊͧErkCJ._on.d|x-A^ vS G,祯_ͅ겜\S d$H]hq5(=fyTz6xD;<U6ԓ>6 nu͐?[ Z|IDATx_I+PS sJrt&C!əH93">9$9nXfZ?px/n_W|<ըqm`0Bj:Rb~= 3AAk@eJܥjYʌ&[/ Ҡ3^ ezCg몘_@ay ]pytt۽Ix#⮼K_Cɨt̓oo'Yjc%_a-9L-6ѻ{3M CCSp<7UzzKk&5Ag}f'\eq]XIsε W]#>Hbnn]MM+tzV{f*^->됺@ ݦ w[ \]TBs{X>MwjL5r ]ld)!L,ݖ]ĺc*ᅰML<kܱ]; R=t}{=+$*we-S}}tyzko<|#7z[ku7Fw=i ]'y$葙xORG|,%Ǔs,2@k$I2zԬa42_!wx*! R]v,pssk9D{gK=OqEOFB! MB!b8hB!AB!B! :'B!q p W=zt$t1Wˉ82,Y",Ęc JqHR{5;c56g:tf#wjEVDe@r?~^(61=u ޼y#p!pbRZ7LP#%E59: НNدg@ת![ ƌEj<4:IjfOt7ʌ#1Xl ݚj/]|{;|^ǎ2aW3".gl[d٪ijJ!{8TycD ՝FZK5톏-q ]ar9Z Q}V&ͅ.Ωe{O=}zl.clRu2SQmBFZTAgJ*?.qߕݙiA2$tMJ8uvI9gZſ*tƽ9`3܅d6hk7#et~A3t1x>ZR`;@;wm^sB!b8hB!AB!B! p$B!y#B!b,"m:O ^\FEнwei7u&ݡ[XS.zMEjh!-XrJnZ{-66˼m$<?UoOB!0p$B!&!B14 !BAI!B FB! 46 [ks7Cqoz.dН=\M.ˊ.r|t=jVƆ3E \pcG2tN#Nӡ+^/ )#:OBe[n,p֪Bt?:~PuZ.c .,ߕCOetKKeE?BIRv7tJi2>Ie*LtU0}yТ_Cvj n7|,oIyh2tvd߿yظ=i,̅nM]ӲdU-pꅕδ̍^'jZ&zuW׵VН9Lz.zzqBY.3mfz\ݍ>3%s+~[NtwW3cZ7M)΋=uVנ{3t-C({bеY:X[7>Rk :%N M|C_,R=^ ݖ\[ܥjY3Ca(oӏ;ZX9zLӲr};"OΣn5ۥe$:B!B! p$B!&!B14 !BA`ވB!t̀;ȶC.HӦM{5˕[&8Po//ܼs-U30`wВ ZNbI<.{On]jN,qj*!`$t!i9jQ4P%[X5[=-e%н:~npN'C_n̏䞴<{BwuqL8/D6v.tq*¿íojL[~鎅JIA)tn22[/vAwj|6 Nʼ]ؾRAMYu^q.{dk+X ]Jwtg/-G gK" ǩ=ZNw_zhrH t{Ũ+t/@WEz$U tu y/^}n]j)+5S,àz/_5KNM4^Ock~%tsՌv]{j t%L YMNW3amN[KZqǯln͟ !BaI!B MB!b8hB!AB!!BA0YIyh2]$yQ%t-NHTLOJ/_^]mtUw!tɊkBW;Й5e^k럻Hf)HzF1t~NΤ;t oJõC#Չmi-tfҰ kbto>SOkޠUvQ1 UYR;OZݓ|Zn ?: G:?..J#;Ƚd4ilpvn~Ql*ǩgv~6o~g6m&p ]/)sNjj 8Kn@.r_Qmp'T]'j+OЭ4JZ)'߷4%u2g 3wyU;N etcAtN!B MB!b8hB!AB!B! 0oD!B QD8hq&K2pI\B[8Y ]ӧv t NUS Z;p'tGSK=NXcN/y UeX/t=ʹ/tUEeN8f\&ECW#9)V͈h9 -e`g|]͎qJǯlԒJʆZ?qR4S?7Utzξ;N}셙*j.Q׵Ѳ~[q,c 5ߤUp~+ݸp;2L|۟]>-t8o4nT]tΪѲ,CIK5oT_t&&W>)=`wLu]kǹѵtDzM(S͙i{Bwu4r%'SM8yU]]-Cn9uђeZzzBԵcI5t!~PezCg몚:~OB!0p$B!&!B14 !BAI!B FB! }u14 C555j^ov3d/z"4gYe ])I?K)y^c9W?}`b&*FጁOe!|~3Hr_zL)Kp8r=R/+?c>O飡/_t b)ԄvNݣ}ˣ˽|@|q(<+\}'2yRM.pbv'aC8lU-EM+r~-oBjD].:3hXW3a<|+*.QFםP+>ӗr,c+:'B!&!B14 !BAI!B MB!b7"B!q 45CVKejf`O²o+N~d>!,۟[-[@1܊S(cgB78y MC7ZkɈn}ݾWO=4UMV݂YR3:;T^BWI|d3oj:Z)z*JռEнyR6.D.pEJ~37%peGs4% Ĩ*uIu~]`Q[=$vtQk%&_Lˠ+>xLfnK!w5;cc=t7EpXZUЙ.~]&?u@B2 w-ߤqZ]y㾵>/crlq? A~/)\v:]ĪStUbgmQ8k8B}Wi箭O:~Pȟ !BaI!B MB!b8hB!AB!!BA0_pдzax&XC?RMhyso5mDf' .ҸRRP o- %-gtN!B MB!b8hB!AB!B! 0oD!B 8h:L-3K;롫@ոWAWhb%];@q<_nKBΝL?YI[:#y|,+Qs 3~&DvAU |=^XNM?:He8rZtt{FK5=|aoh ݁OԔ|oZew;o+cM=]̔x|* ^83?ZbrB=2SL:OgEKhL79y5_xlI&nVu}]GuTtC<4:ItGJ)NLT!%Mp31@ͧͺ3EG_B턚qe;t7T:-Ei8 6`\ ˃O< mqZ- 'p6?K/n %N٬4J ͎Ʌnk̛M)6s4veo,SjI[ճty]޳~)tm߷_@׸R9 :"9'5Q Lé q*@粢y^pOqLP^\PI88³5t?N1L.x 1TT)8ST4Zv>$#v%_ R,ZRȫxr/PMQ΃.MjάtN_W?gǯlԔ pRp:jTV&z4iCWSSY9>d$C7zxB'q"]LO'jG&~83U&sa2LwM 8]eտT,<MgjtRIu~]`Q[yx4tmrrJ m&ˌǽ` 5{\"^]$\KHĦRsit˵S2~]8є|ތg0˹z2 #9!B1 4 !BAI!B MB!b8hB!!B1}Bg'؋JʆZ>fRF̓ ~// *tG-2@k[ ƌEjfX/t=e)td#NDHi2N8Lf/܇̱gjI׋'c]vM$.$-GMhɖIǠLq:MjdH^K| NM?:HӇ2rerN}oAguVf\i}1еjH} BR_MnRDYdegImi?}`b"ѣ#9Z}Y4.1N-ٮ@' 5t^ɝTve8~,p]sk%e/tO×x]n}ݾWSK+/-cy>TʮξUqL8/D7].T +]wæC%O7tE6Gϥ3pb!rJ@Wy|W9oKF4vY sŖЭRʏZ:3΂n6/Ʉqk3BWWW':ȟ !BaI!B MB!b8hB!AB!!BA0\f)+Az:.Psݡs,Z?͓rOBIosyM)NbMTfV;l ݬ r%WS#{¡ SMY&7$~MBtWנC:ˀ9]"pOn 7>jIK .r.jmz;d3PMY9Lji[n\k8]/!ZҲAOp*u ;ϊߒezϑcFC7a؀cwYߛ߫j[Ήy})Uá{cuLw@wfZ:e j9yt_]!Oo7sw' gaϯG z,~e"$ НNد&ֶ 31 dOt7Jnw%9!B1 4 !BAI!B MB!b8hB!!B1<"'b]>#Apbi Yv  ;0lt]Ĺ9#֪Y-] 82X~? AW/y'F'NT|,R5 :ӵtygC~;Y&.z{?w{@g()Ӡ %XAOytt۽ mM4Ʃw1 h/um#$B<:S8нyFM GE|LmL|ҾNI=|a]-/Qr߽ΫQ3II.i7K'A8,XM8-Nx'ὧ&H@g%jVbT >ϮTd--ߣf5R:B^g1>]Lvi'Bz3~V,皪Ϧ׮Y";w5[YZ?$z΀; ^\F\}ݑdwD BR}7z]Gު%lu8"JӦM{ 6cwJyh2:'B!&!B14 !BAI!B MB!b7"B!Ǚ?Y6ZLMM| |;A'LepZM\ ]HG+9kAXwl]2tN#CQ9Ėʭ)YymBmt_q/k8BVB.UɝM2Ut͂0;t.7 sGYgеJoP[ۂ@7+8o4n}GIܤЅ'o" rt6Nc=*O+9*Q.{-,%y8U9W*oAǺ.i?tcZփCwB,y5^jJ[9ܱ];x`ڜ>攴$vuv<\z\ɖ}fstyլ9mמ{eC tR*;0?+DzHZ TjrzZG{1{ ݕ6R'p^XGcwD~ t_w^I[:#u]OsC2rerUBZJJ.}@77LҎeOρЅ]?>cھ߀ƽk ޗrWEȋ/kvBf';&Y#{GVK%R5t,eW.n/-@g3B}o:Y93-R;?B!AB!B! p$B!&!B1B!`hp4>-=sk35FSܠ;T _T,ejt#dY$n Ҹ2j#%CIKI5t!~ >Sj"FK܀%~ft8WSdsTnZ5ؽU&XC?R*?.5w|='&ʕ_BgC͠d؎Wq`|Wķ7qFn8bտTOΣnL )jG˫٬5i% ̬8wzYIV.n&83g{T@w<\l s{I9 @e} x]Z4ǧj3SEA[BwstqBOsв]sռvG.u+Jx-=|a.~kۘHtz=7ŗa䐴]wæC@eyf5e"$B7L< |NlUd{#٧U=d!i Й5}8Hhm//\3]d[k5 fɴh :;覘J|9!B1 4 !BAI!B MB!b8hB!!B1Kp-;]RqG}u1? m?-[ULV8ӰYtWFE{&l*J[ZgOt7$.UCRMPiovhkwX/t=e97/\ r}Nscz)V%FUI݅yt^'ʧ)Ұ 羌WkjVGK$kiRDp ^CDkrT"qt6W-S&ͅ.2,{o.Cpjӱm!J{nQ57VĹ)tEίՌEJ_Cvn|ܦ)>uy8gSeYjl>l:tǎT3LZf*ȟB!B! p$B!&!B14 !BA`ވB!֕U6J|R&wȀ2?]TX4b /ﮐ-pF s2 tftOg'C'vZ= 3Ajj➴<)㠋 :(nnx(:w1ptj#|Kԟx ~I<[F޳~jAK4i -kׄ,.m<: jT1e q*_Z>ZH˒u~k&5bωK=^&V27vKV%M᭠;sD.j5rlGl;#ЕPWNPM(Sh)m-,n{RG5Yy4tmxl& wAg1{ ݕ6bT7t> Е͗3D: {pkB _{d|[[BKw {d&Z9tT^{/lZD̔[n{i^3-T74:ӓdZҲyBqӮ9՛9!B1 4 !BAI!B MB!b8hB!!B1âB'漌#;C;0fXX]RK 9%tW5p!bHLRr< :abto>YMNKKK誫stymTܑl %s[@Y.jRhpX\y<>mNI"}Z[,Cw_\O;Xw?+DM^Y9<_t-W#ҎA6`֒;rYIXwl]b[Z ]lBWWW'yzex]^-4 kt|Y$U׋Y4~nkc=]|&o@w3gݧf\ƙ}l>Әi;\\F~GwN莦NWӍIFx~#Ʒ -o7@HV݂Yb) { p=:'B!&!B14 !BAI!B MB!b7"B! ]p30[dfsn^й/˘}Bj:tGC$wnӆO}X;JMx~Ѻ<ΫF15{-;L/%q>g >\T}F9d?tNP:'++jej"+"՜.:3-Hz⿙r=R66i.^@pY8/ɄqM ]xf {%ȟPX}<[].Y?)M> äj.CKh̺WGiCC7EݮR5 :ӵr{fz=􊶖 ݦG4&y_-Q4޳DǙF7'Fn{NH]guvM1-WpΏ ,j+};攴}pD(sV7TUڳy-uƺEнyRMjiw89hji I_ԴS";B78ɿ:LY[ ƌE2 ^>Y֞xUJ]m#%99Cz:'B!&!B14 !BAI!B MB!b7"B!;R={þ$OxZGˈhًE̔Dl_ׯh eCg@%etIUsJZr@K% I7L/n eu8"JLO#sR=wRB%p|`?{|^ђZ܀njdTt}֙o>S]a>j#R5t,|ӶJr_BjK0ۤ&wl^.km\Zy p=tRȯ\k7PC"DN$>>z>f!3P<\T|е\U81Qk">;dН=\͡Qڽּ*}qٶ g|fۧ&nmpɨjk7~MBtʭx-YRߍښגBqިӤq[!tE)"m~d۳U= 3A: äWҚa߿wظthiy#JռW>&bV\eG|J"✂gQhBWUtY< oݮ2$ Lx {{Of3k*;qfz(R-8gdu]> >Ϯ+OCf`j6%b3& e}BMziϭikWKi ?-4;F{]{ϸlݎ29 '81 }^KiN۳wFo{&[e%ub)^tWK~"uvM1-M'M>FB!B! p$B!&!B14 !BA`ވB!FBx/^o ϥstyǥaYt+$&5KT7̗Aףf"[Sܠ;T vĪStUbK.ĩ.k&5-3Y.BWKahw\oJܥjY8 j8Bڷ/%:?ۣN7Z.ni)zv@2S-t*ī%N>^hkc-3 ^>B|q+<+\j>SjsXm$=W8" [@uTȐ,OVSKzy >ϮT8ZJMȆn)#:OBBpcwN#e/*ux-9Ur~ -7ΆyVYg7%n\“7s_誊.nCP27;p'tGS8UE  I2y[V{O< ]e)t$6u&U+ wAgSt)cO8z%\$Fzj!{QMZZ&Ζ.|ӂYjF ^\VA)SMeL/h1/Jۉ8Ih_?88㎈ʏZl.ۂ@7+z,wRB%pZFE{9gto޼,àzΙԫi?&)!L. 2~Ck"-t䑺GZ&⹠z+9`5c_O=͡kl:tǎ{?A(GFM5mׯ_g_T,=sgz.5ooݙcԌOr|ٹ}881Q ]ꈏZ.@WEl :η<_/@)*.Q,ݖ]dʫ$ɤY1{ ݕ6hЭ\'V.nf|gQ4"cFC7alcy4mo2aQ.{-,!o}HPsJZިaY:'B!&!B14 !BAI!B MB!b7"B!pNLMM o.+LQs'Rv7t +O㿹t^i;688@7T$.$-G{yp t O?n`SO%>FFE{ 7sI!U˷,ټ۴ᮔԙy>ts B '++jwz*4R;]RqGM&iɫ)q*ILx {I×8b|[Y&AWU/ށ;;:]=?ݨe䕖ўkg5]lVAWtꙞNoYi~Kp[&mxY0T7ݓuGӲAɯpkRDuo[8GGBsx/9Yk5({tN!B MB!b8hB!AB!B! 0oD!B BcKKK(v<74IZ #t :( \̀9]"nnxgDZ稹!%MpCw`@ {ʰ|_{dɏ+B'Dnc"}f)QBӘA)tm<4:IjnaYm&^}C{ҎuXBK2p+-Gˠ+C7tE5!VkS(fKNpX8iRdsTJ0iR!-s[S%~KBjX~ݛ'-ՔM`8Rˡpf̏ԔFC[&F:+ɖOk; aӡgrWEAsׅQ hǩ]-޷g0B\=-fu=q:tW+ڱ ˶J'x`n/'k<'yҿ9/ԼصS2%-8x@0t/$%Q?Ki)mԞmO g>%-:'B!&!B14 !BAI!B MB!b7"B!Ng$HBЅX"k A=WCr=RVbY)ڱ,t =8QVfn켎@W;B]Ǜ ūF15{fRSܠ;T |-p:` 5`c=t7=i ]'y$_T,7-A׽U7@W7_RlBD:d>RIu~fQ[G+iv:^cTĸ>mNiVz>s$#jߋVН9L~QgK-#\.gN_a 5+ԜR]mY^Ry > Zl ND.+U]Vih$mi-tfoӏKbsB!b8hB!AB!B! p$B!y#B!bRkAsRDYdʫ$KX@ĜL<ǪɁ ^ϭoۤ͡F%s܁n.j&EKKb>^%V=|]VwCG ĉEpX.y@Ak4ͲmDfۧ淴sO~37%*@ԥʋ/kvBM,5tk ])Н$ۂ@7+z~ WK7>GZ(&^Zn.L5-iTO:ep55|t)n⛃smY#7ɧ}-n@7Ei^;g h/u]Gձ2Tӳ;`L09F}VJ;NjLꆦBgz2PJjst6 ޼y~/d`zF1t~Nj2IK;i.mh9g@ת!))(ANt/Piq~&>3sjz|>To߂Y?B!AB!B! p$B!&!B1B!Xhir_MtljgBԔƈ;һ8wtg/,Ʃ]LRAXVB<i $s³e_cQ4I&Y3)ku&U+Z!;_^hK 3^5}NoнL ūxr/ϳG͖h}^ۮmzt[Miv,UO wAg:t ?C2 ?7 < Դں_\[yhm2LrYEZlpvn~Q؟l<_t-W#Vd@wa'k.-+[4InijCw`@wwsO})IF# ~#.UXɕ_NMݱ];j"fJtQU"B''2m֠Vmst?]!vAwjTns ur.j ]k4f,ndZc+m$5~ҚI$K^&yW˰X:e.CWq`,Y5^꼤LOB!0p$B!&!B14 !BAI!B FB! 46#2gzlYEmݬyԬq\<4:Ibnn]MME*M0iCf/ieH@g%ْQ QY薷sT7.URqBO q,u?rJ~Kp[)U𱜮i>ިI4Ӳ,}ҸjN{k=o~g6m+Ʒw๜* jH;AW/5!=tL9vk4tûVxc8B?Sܠ;T ܼs-ȕ$? P?Wk :%jrnYm&2B7o٧eԼQbo^)-pRo5KA`Dy ]c ߇dO:'B!&!B14 !BAI!B MB!b7"B!hK;8h.e*Wjt | s{Kx^M΃.lВ;Yݧ+?_AkY t^'9FnR 'nj>9WM.LENE-V8,۟[Q硳ig| Sۉ{RD렋J](_?~eq6v.>hσebtSsR`Z^ej)~`@I_Ķ 3 ]R:ޣe`\B[8Yz.zx|#Й:}&\zF1t~Nj7}/l&&2mW6=&p7\S5Ug=ژDh{w}딦%-7 pNmּv,x/>fRFM7!ݸyR;fr- tƺbW3v~f) {UU[R3:;Vx}n~&Ҵܗn5 [sB!b8hB!AB!B! p$B!y#B!bk!YG;NV\eɔ&%>Ws&5y _)+/3΂n65PRTtpK:?.T 6tptƽHk?Hk&oatݽTd٪ietTQs<l :ηd\nWsCZ6HK?&Cg?Ib z*ƹ!NSլN#=Q*O+9U.iտT"B1cl<]ĐYl ݚj/52=L}h#֞8SgeLt~iڴ)t_}-n@7E53=gBvOt7=i ]'y$61=uVSDR;3-H͹hE'C*AͼuG+2Of]_ Xu}T[8Lnwx]e#>ΰ5S]C;utl&X-- sܢ4Z0\MK>]I䜛tr-fh7OZcFC7an]PqHR{uʿ?:e[nu;HnB!B! p$B!&!B14 !BA`ވB!߯|v g6BɀW0$9Ie3P= e=*.UXɯ\k7PJs-y)W'+jaJtQUZSN-ii +5]@辵>/~nuQjJ*sBQsjkKSiɏ*'ٲ~N,e*p"5ato>8@MPi)a8u<\=w8ըXT 15q) ?cxZo{]Us55:##>HҪguٹJ*jNTd{K$m:Ldkgz}wrZ3k%ȟХX=-G7 kt| ҲV':/˻+t G}i#-6|t))Ӡ %թ ^8?Zgu[Mi󄖜 =1}¿(ƽźz*o, t^'NBwtԞ@`)5Y?}/Q΃.M2eKܤЅ'o~OB!0p$B!&!B14 !BAI!B FB! 4ֲA/ }29kiK@wr$a%R|:IE\sNbSK1ԅr'MWܫ:\Gq 3ǞC׾LoNY,ɏ]L|W~ ]?Ź)tEίee.tkA NFtH] ]{54%tgI&Ǩ{dò4WLKDi4ǽ` 5%|{7s7qFn@we7 ^ןPF[ ݁eE5ŧ% Sܠ;T Y*A=WCr=R}6Yrj<<6Oˀ]X/Z(Mϟ !BaI!B MB!b8hB!AB!!BA0:t&4d'PXvв{¡ N/*S IQ#mq: "RM#h-q`T7t>Wbk.Z7d3PS_:-)CJۛ(釉HzE9ɯ\k7P:+ɖMq2jеY:XM Ț-jEKdTQ5 hЭ<_k}{3z!KgsfRO=t&Hrzf*^-q~+LuXqWj~N˹$\3b;*fYU׼ytt۽IõCfY>>G<[].Y?x*! ^]st?]ߡ_ٵ*!jm}A`].r9}ſ*tƽԋQ_W_>fAӒeZ𞴅<8LwKM5!6;?G[s_eݒT 7yϴ/Ʉq܀%䌅.zdMOeX/t=d+ϭG@cI݇G%vEm7"B!&!B14 !BAI!B MB!b7"B!??5:@y&sdtIWp&FR6 \˜8ճe}155N\*505v復 kq6t#ʢcЭ .|۟])[S$ν+V$Kk&'++j-p6!<\]P9t!ֿȝԳu $]jq⎙qn 7><%tW5[LVu$K?K ݦ w\FͥЙ[/@Wy /Pn}?Й| ~)-rhw;^ǃCiu}&Cg?In'JTn]P5V.2蠚ckޠZUЙ.rrkXgr5s/kgy/ 7)S^%A,X¢B'|3L{GK jBS2~~3H͒i)7-/sGљ'TM{177ǮFNyGIPO`Lf$ ]2% Ĩ*y_~f<͟ !BaI!B MB!b8hB!AB!!BA038hN1-B"$Ƞ-;{4|'eJk8;c0B\z3GM8Tjr|#;*?3;W[ ƌE &!CJۛ&[|M[@$٤A4@~]a<;o4n؎? ]Łj2iq:tkդymBm5;e|kax<e.3.؎jefVSn}CwDvuQ]1~uJG{>T|:G+3i :ηJ m'Cwɕsa^+ޱ [nrQ9ܱ];p(ݫ]47&ХS[݂֯%Qz:'B!&!B14 !BAI!B MB!b7"B!U((tlv=8iV!eà;.pRa~i&юЍ9Q.UCR,Z?͓rx7tC0'\ze"^TOREеp;!Vd@wa|`?{$?5:@I AkjtVkltfKd!i YmSD:ZFkTXMC7I5t!~GgA{2E'[K] }2`3NT\[S,C꘸Aw&@ʽJuT,i;GC׳W R',FE{^-eii ]uux]ZZl ݚj/I~I%>nSeHNE[.C3KkӤq Grk tֳذ|_tN!B MB!b8hB!AB!B! 0oD!B юq97oZ6᜛t␎?t0tI&B7L:~PeXw5wzz.yIzjBKp̸?;o`!&~!g$Х7ڭ&V%MZ*d'tay2y(ӳqb؎kh4: ^f̃.k&ܵ,m8ݱ`N/y U%F0T^@p/¤=*5:fu{'uђ-a.WOh;y_3r'c({bĥ B+5Gw2込B}ƴDg}4mׯ_M~'BԽ:Ggs5-1tWjH~I&>DZ-xt.H?K|Wq:IbtSL躓6&4/nnxbݱ tߪ]]Ǔs,ҎA6`,][+7SVWkj7}&^K]9ß !BaI!B MB!b8hB!AB!!BA0:W5Ws.qƣn1*N/KV -af ڧK}W tgvt NYsEYoe>!/Khf/559SK{b˯\k7P|q)&@]/ .q^gyTjrXu^:?.Ph7OZ8-cJeS&5RZFKiT.΃zXL* fR:\37EίeE6t;Ƞ;{\~ t#F@QpDƙ'jkjkKEkMnE]f tYEAguVͮ#;Y2-W=S\T!w5]u) ~{<% N$XDkQztdGӏRYõC#CJۛ>+~]xVX&AWUfԒ0f8LC~٧)2gD趜ݧ>0ik1trI> =֧} c~QS9!B1 4 !BAI!B MB!b8hB!!B1Fi9E5 %3LJeb&܂jS/mJdL/h#,+'{vCWSS&p,W%Ǔs&1FHH5=|a^kky- vn)};%.AV݂Y9rWE! pRR}ZJCM, "j"r+ΒY ߠ{7\.ݸ x,ndZ}3)^I݅yt^'ۂ@7+x|M艦EiǠ[0\uwnӆjH˵i)ENE- 92o[fB5KMCgF}]{oݙcDڵL5]68k6X]/=>d?tN@weLnߩ{=i ]'yf2vղH];@q,kiMX{⽼2Tݳ ~Kp[)C7<_t-W#+?碦9VSYCpᔯlt]DwwsO};,qz[Ffi⿡{zv 1еjH'tep5ݡ;~t$ݤf=n5KyrtHotYC-W]o躓6*ezCg몚Әij^eŵ_[֫<_S!E IP*q>/ u5t?.Cp59%wVB.U#g|]͎$o-t39e0B͋i-mDfۧx~ ݧ)z!i92% Ĩ*=%g9WJW tv;\ڻe)t4wN莦Nxv_*q*uCS9!B1 4 !BAI!B MB!b8hB!!B1[dC󍏔OqXr9}ovNyjFDK1h -SeClLy]b`Rs wUjIK[581<<6OK] LT3 ZN"^;R%W nS2']噿1tdOΈd'˩b~4U]/2@kK>]IdQ .@wwlpvn~Q|6 Nw}&;m߿wظu x9%tW57&+U] >Ϯ롫@z\ݍ>3stye"֟[+r%gTGн|NƉ': 샓PW{SRM|u&U+!o`qؼ]趔@l.Y^3SM=g{NYbv>^5ٻh5+]qnǸ#c]vM4,xEDSL5 gL RwwnӆjOKi}8G81Qoɟ !BaI!B MB!b8hB!AB!!BA0_j@sXxݛϤly(3~&Dy-r G:.PmWCY)5@goS&j>7gtY#7I;jLM[hy-%M2*=*~kۘHmu-ev2R %wBy,]ofKxV:?$׽T q,5ѵtin}ݾWSg_^]pi4558dtKp#Ud2V{OMiKЅԏ2 >Mɔoۤ͡F}nv ΒeΑ?p{GvNg$i5-Cj,b[Z ].I/]QsdKsq ]ar(8U-pꅕdT6ͺ5R'/̅nM Kk5M /-E8+X組X+ǯlۼ]趚}Mfe_OGgsR3Ou_҆ZM{\*OB!0p$B!&!B14 !BAI!B FB! 4r ڿM ]xf5xORG|,Uȷ@mtF,SRtE]$pQ3q.j ]k5e֙4r%WS30CIK5a_ Xyg6^nyj"&:?ۣ=:ëd%teC՜RKO[UEKhн|Nz.zTvMR62B7oTVjE[/Z#s64k35F Js-Si[ e2USYqꙝ KZy[ɲ/qf_S_&&.Mn5ͥ%p ݦ weOo؎? ]Łj-tEm5{|&S˧iAK jXgrNĉG',"o+0e> }0 ~O>%Fmw|&˴y}W tgG|a%2=> KǎT{|GK*?OB!0p$B!&!B14 !BAI!B FB! 4($[:飻MjdfVS=ݒ&_C;0f ]+Ȭ8@}FA.OuE.w8ݑh䌅.zdLn {ڈM.LS ɯ@7Yzo,K!e'KzF1t~N<!Wմe|}i-#+"=jtVk#tN!B MB!b8hB!AB!B! 0oD!B Bc- Ų &!nҪt\eIwߔ)Mio lB?KL 8턚ZEh #$#jߋњq}ů`)tn+Zo{]{NH6<6߷_@׸Ұ, :jjwDMh-ҾE t_-#2"o| ^\ǽ` j3%!`$t!i9jGKx{V25v%Vd@wa4|#'ez6v;}e\nWpI6x ? P[5ܐzٕjE˵iW^>6{dĐu&6".+LQTiyC_n̏$y~IoSDnc"=ӴwCJ˕[&ies_誊..~W]Uk NAxD.pXwl]e}B68c7XV\e*@ԥL-=m9!B1 4 !BAI!B MB!b8hB!!B1FAj`PAН|VM?h_2m~&.@Wh;ɨO͇#C,t PSZ-t*dbiK ץn7;R3C&@w:a]DS=Gď)tuuuj#gn-%U].i=ح vX2^n2$ )_o5ݡ=+^p݀B} :FԵ[k :% ~n);B7 y(f՜˳ckx-]Y2ϭ=sa%jIKI%pg1.BʽJu NF\}ݑ! R{Iu~S_&&bP9t!ֿS[]S^%A,XV%MYsEO@g h?Ҳk{L0m ݬ \sit֫围=K&ď,x}VOWyV_ЮoнLZ i1^gk5 #+"|ӰX;e.)x %Ofʟ !BaI!B MB!b8hB!AB!!BA0xs"4uJS!op*$"B& އ66'+y?ty/ʺ_peKZP3 ZV@7Iu N31@&ɏFe!Wi ͙]Mr.塲:etAť B+5qef\6nGz܍ǽ` 9d?tNPvo,Ԏנ}l4Y9%%q :ׂ\Mj|4veo[.C3&äjʲt7߷_@׸jzLk1trI7ŗaqjI6>h0-oT6[S=9,{bΫyZCw`I4?'1 >#A,ˠb/≍Ft7Ke[f%]817Vqo]lto>9!B1 4 !BAI!B MB!b8hB!!B1FiS81QZn}>ShɁc[7[N/y Uūx|,Hi28L-f3]9,'NH~I&tc%&5K>fRF8DXIms.ɿoquXBAz%\̢9$uUX&Cg59]VU*VjB%u>b 1Ӥ%-]jqꎙzq]i|u{|SRy-Q=G 5z?ڍj6R6tt^I݅sשYV{f^wD̙iA|е\<ϔ^Brd/-kqa52WPiys)SMi-VݒT5=U:]Khazf}WIP܀%tWK"|ߣ{6o߷F#ԽbTV\Z*'FUO*[p׶+tV9!B1 4 !BAI!B MB!b8hB!!B1Fo9L=)jHsڿ~f>Aeb/{|< S8A=WCr=RāGj:7oވ{"L߄.tMwX ggq6\;q1xi,,CJۛ(.+LQe"vSŨo;}?oӏ;Z2>ށ;L&,ykE2=G{ڈs_誊.i'-a4">m#d!-XrJMei8@}$Pr tZ%x]ow|/}y^ceJkuxzy*-%t^I5=|a>cZs)GFםPu/pnoG޷kac J SgW=9WӺc*ᅰ7,"Ե-i|W8:IG ]vҪ_gvj&l"֟[+/ ; LLԄQI~Մ۳h7OZJaN|<=gJ|qJ^ 3C=b>#jv%Ώ9!B1 4 !BAI!B MB!b8hB!!B1F3A#CX5[ Ț-íob%2T*^f!'?wM3)M Irk Abu'覗IǠL&~LBHMC7)!LBn[688@7TlҠ ~ @]$^0\ g=6?KSHwByd_.l(NlvVfB5KMSK]=ϫp9U!NSյU'&=i ]'y$u'3uRZn 2=gBd%kdOo*)(A\qJ́>y9j*iӦн~ZZAU%uvM1-W]-%[ʽJu[Ud{Cٵ* e"@jVAgVD˵=R[qWv'My]b` jG˵}p-ȊHibԙލU{~],tӏRq\H jcԶQׄ6Lnn<\]il :'B!&!B14 !BAI!B MB!b7"B!1V}*,vnӣrtH/&g-IFOwq-N9wNNMV:EAWu/V~? OWew&Y.|"ەQ-h)MK|RyS= jRk v"<}Bw/3U{g'Kyh2tvdΠm9Oh-Mc97/\ rmۡ}>SnZ{zp'$-G$5aj.J-Xwu';l:Tq^lKkp0K^B7xUso]bژDx "${݌x/ѷ^MdB8Vު~ ݧ)?KR1еjHQPq\[s6QU^^Kث7gTY#7-r>õKh / { u-u xiUgvR̬^XO:j 1m~Z7}&렋J].UsB!b8hB!AB!B! p$B!y#B!b5~Le;SfAߟ GݒQ Qg6rS_&&b&yHy1O.&@9]!w5_%bp%}Y:[w]=]25vv$4fFE=Ӡ$HdM.hE5cd"-\524`"%=:T|>_sާ/R~$]$ iS9R8-Z˗je+.V3ZsF5tmlt+ V{j7lP#::uЭ(_G3KK}[lO;[4\3qkg ҵK2<sޞR%^YK^.+p^Fe%"PϞ: 7*TݨjK9sƫY5caaݫW|tt~n]gR[*,3+w;svcK%>_Y!ssp`q ]ibq)]]k݋ĹYE'$}t1meťj֪.k6:'B!&!B14 !BAI!B MB!b7"B!mM8h-f4I];W=$ ӧO9vɂӠ~頚pH|0V@~5-gΕ?/ ԴSd/ gtܲ 5bӥ9t_˅ *c?xsCӥpoP @.şqL3 ǹyp2)oa5O5es;/~"pN£IK: 4yk ]FycSũiM~ W}']Ź3tE7Լvq8MZO'8-.K͝hЅ%mg )לajxQBEK Kl{نsQ Mx ~нvYwYmѲ3I?@8A$Av]+b62:S5hٰН?^F'C" ˯ !BaI!B MB!b8hB!AB!!BA0 Mef-i8IIQ-t2~e̹f~ 2#*4 jDK sޞaSDs՜) /j`˹`‡ǫ&$tIc&Qе|) opNɤ܊SR+nڏ% m~- @4 MM-h3)1meΑ|\u{YgDpW]KԶƉjr''/HJ8!f ѧtfY6;;AXMiO{Fg155^ZĢ]5tX:#t)Kq>O{lvDz%t555✌S=ES:{U+piZ! zJ}eG#Ϳ;Yf,.{ډKs ZϡsKSikݥ QAWUtMb@R}^v57[nξuLϨfKL\tjJ[7WC׳6Z|vߙ>8?ο[ߩƨux1sWzu3謢/mCi4W^G]'T/eVJ(~uN!B MB!b8hB!AB!B! 0oD!B B{Hj/tKPz_:]RYmR\FV2lMkCd9WaN70"N#|2$ZZUAgZ~ ݅uv{/ƻAgW)!L$Aw1 W}~iyR_Ad!C&9+@W,q} Zr?9c\^9WsQÝfW0ld۫ #;K_;_M4F"jz_J+mB9n.$\ME.`ۿt!?StZ=R(Z*I$΄T\ɳ +A 5oy}q;3R{ZȦ&*o.Q[Z-/ӱoۉ8#(E,_.kA?u]k9,w3KkO&A9ndl4 Ԥ Н>8t|0VMP]i~ArKZ_!U̠>_&⟛fwǴ:,Q}XTYϗ^R\#+H*Z2eȘ6]j6(6p!taI$-t3LJi9NP3= wAw\pBv٧$-}@|}%еvO=НH>[5v5X'plֻe7\se5N;]>AwG1"t dž~ W}'fkX){Jwi jF5ꡳ\h=pg@2SuKKՔН[2sq&m48q2+[$]jq.j]K5/R~d*Nɡ׮AK z]'phڍW~YBl.u4S^>Xx|R {79-wG9{~2vYzqo2:'B!&!B14 !BAI!B MB!b7"B!蟤 pд IDp$w;'MQ: 48 :۩:c;tͽK`$tIQasY $}t1meQm}t[M CW[[+i8I_ֵpiڋr5'iǹ˰Н?$~8%M"{)[qn!x4iΤXY걥j^p?'wC׽,qiM79Awk5ѤeKL|kHW@=[{V6J唫]}Y]ĆbxդKs Z.7wO~]V2O$UdJ4^.o_i3`4_:(;b7oA5_Н,UÆAy)s })5ǣ6lsjK;#Wǟe2DZɦ8AdbZ֪ t&&Ԭ{]6^v-fϞY2$ RX+t}m>kDʃԹiHe3>_K}iLFi53]; Լ2}fg⠫&5Oo.RjOsB!b8hB!AB!B! p$B!y#B!b:܅fj@KiYZ]/+d+.GuNj{\@w Qf[dB畗K:]Er0/vn{ -e4I{UғgAW~q`MԔͿf8Ax96WgΗ@wOg < e5We!z@w(RYB&N/wn^Io ӧ2]%yte=u6]CWy\HPjvݥmTS!S6'j˨_;} o} ]ә-K>qUB7lR6$kMqie}zhg];l=Tsf; 7YICd%tkE(ZO=НHLKxҠAw>/Q=#}6@%}=I.}4K}UDt:f4T]3c ]BD..,i9XhI4.Ӟj'wtnkԹ@˼ɡ}7Vs_kWӍ_?~i+CyqV ݼ2 ]AR4I+|[bWZ].EH/ ݩRN8Up࡭'*ʢ=92ݓK?82AZ@WRAW72Tfg|/Or ^O$OA.K+ V8bZ,,,{ ݥY2bvήY 6U昪/kKs@|[tt(YU",汭S2FX*իAgFM&ٮb7J)~%;NnޢRvt{]6^@~)9 5t2WkZN{ڹe|WBg'W@gެنd˅j %9twת{ݚʚ]丣2 uzjNj9!B1 4 !BAI!B MB!b8hB!!B1M7҆[jw8,$tƈ)t:-d?t+S?cpw)tCmT ZvFˏhEKF]%2,x*tIIB8:O*ֈqǖJCLLIߠ[ݻz;͔;C7i~Z]XK\Ŷ友dHɫY?\|ϼfnFݍVs'}cK) SMy18v?v &V~3ڙ@A)W[vBWr_q8%Z.+lк%-t3LSMy~݉y"&X5S< bn@jF9zk~U]b|}D-ƹ8Qнw@}k 8-+:sB!b8hB!AB!B! p$B!y#B!bj4(nйfKs Z,pfnc_n⏓/5\KM*L|i\ qDeM.rQsjE0iNE+%0(5_yws/rqi)|<ϩkkMLdxMtˁ|ct?~i+OCk?PM&i9}jHW/t|·[MI`VBSqt09TQ8r\ tK(PsCvU)V]:\fnRaCL|[ς\Cj>[sjY-*t9KLZKi o@7iwh{c[1;uPtY ;a.7Ag{̹U5  ޮY3piiyx-.;B7/1O6CWXO )?T̈́ N.o,̆n}vz`%&S@'K?2A}mq ]B!B! p$B!&!B14 !BA`ވB!a}-|/681Rc*~ NKK񩩩VUYV>Kw[#;āp{]jT5s2}tc|˕懠z ' I9&,pfPrrN8q࡭,n˅3OGCgsJ :kɔ}ޗAV5ߤ@5.y2t+Hs ^&{nvx1O{6轚rO|Ns?誊C'i'xsCceN&ȽUDR3>Zze>qUs'M"q ]Tutc>Ay?naF;&|)s{b<|*Εm<\G~j>&g9NW6ijL[g8YmR&$tIcԼ߿f,nܱ];R#:gI{O70] j.~MZJ->{*sеm&窆Ag}Nͼik9ߗ jM0i'-M&dL(WB!0p$B!&!B14 !BAI!B FB! t({F7~nu*?A=[7Wns I-wGM\R{JLKlB’IT$"Wxo[D#|ϒft=]Wy$нzJlnO$)Mk!pI|w=Z.:'B!&!B14 !BAI!B MB!b7"B!=p5Kp19 Q@7bJdZSںJٍ>.3C{o|tNVZ>CN-'ݘ~a;( o31i&'C"#7Ag{NęA)EjzŽUr ߡ{lvkiqQEҒXAwpS []V5hNl].ӃK;羽uY3G^A"Uݷڳծݷ:ti}g.n+A <8PS4 :nI Н>[>C}yetOda|?=KUSK@q`zk27x?43QׄѮ}YI6YUs{N9LݯAlznCӥ~~S-Խ%mT'Y}4.`\(9 PIr5ǹAHj-nc =w>9!B1 4 !BAI!B MB!b8hB!!B1F )1ºrzqUS=4yyj^%4v/> (ŀ\))砣S{d`򼷫3H dBY~0 ^z!ZBg~{xsPKh)U["vUU5u5ne}..:ŹlOHj|?7/M+uFٵYzuEҲOsB!b8hB!AB!B! p$B!y#B!bN|( ><,< ̍Wyz$tMQAZ.CKqq5t V#ZaȘ6].c_rǮ;tHM\R{J%Йߤ, I9NP4[C><^v5GN&}|T|rWAF]5h-7e6M.ﭯ2>6]CWy.0L&ԟRX+t}m>'AsXm]uy]"wtNKV8^v n^bL9v {HҞ^=?_3$"\hĖƋЅQF%$M~>{S?ZB,wZSl;Y)R37FM&iNng?HJ1N;Y?Mk.RCLEi[Uɡ8 Ƨ=IZt|jhtܥzu3謢ߨV;5253~uN!B MB!b8hB!AB!B! 0oD!B ݔ,8h:N;/}CWX^MhiU-{􁚯[b.jglOm)-T8DJm*tA~jFDˏԙάnL*%99y#{;2[^dÉ&-Df>f7 t O$:Y!snjG{Z;Mk]lv*:fLJo ӧ`4_:fnu` 훺K;t927tf;^K9RqUlZn83n -u+k9)Ώ/~Mkqjsj{Ϋ1sW3ZZ@¿3z?ډW0^}7V(F]C{oSsZTR^ٛ YsQ%jjj ]}}{Ԁer(tC'ɔ;q{O%\`?[ ]1GZ5U݋Q[{L"i# +E :kɔEܺ]Jj9!B1 4 !BAI!B MB!b8hB!!B1M[fCCMBl.?@W0A~s_<v5I/#1ʀ3T־Ϳݎ@7dqiZBR&[\;C~[8&t^Ts t]呚lKUE(ZUw{Rr*:AɿǡヱH6?>NJ+w0S3ZF˹tE/eHtr%htAefi}fAw^5?-I3#*qHg]R=Z粛t ]AR̶Ȅn+/9{xt#G tmeCw@{n ~ s>vҩ~<|a.wC׽ʲhW ݫ'V9atQ?OGA:pw)tCmQSR;p5ƻAgW2)Z?5aU;/*TU; D￰0ui뺭~<+VvU甫B]]sognח]r';͔8[^\$oB!B! p$B!&!B14 !BA`ވB!S6'R_|:SQ2~el'~Qf"W@VMi2tںJCLLЅ%mS3)ڵki-en4ɖƋЅQO'w@7gsi8&-k}ÆAy:{GSÉеtL~1~-炡 /A|,s.bClnK2)M‰ ,$tH(1>)׿]}lmY.4Us'u±!2CgђlZji[tPMB9MhI\HPjA抔FCS&F\{d-sKpBe{5y$]}̈́.>9:tQSY9xtƽ'Jr;mֻv%tkZ{K98:i :f&❵q[ev&>{xyʸנZO*vxUɅxM OikI;oYW~GigLMWB!0p$B!&!B14 !BAI!B FB! 44 rRv(]#f`,nξur t'Nng?Hm^~ OlOٙL.͡Z͏h--Ntj:WMMhne|FPrtk:D6ę%Lt'RfKs ZKxAg-⓻ t5 ?xpsԜҿf?AAx54$ W|UĈkºвVroSWBg'K\A~j"moj-_*gh ]JaT;@g=T"'.uߝf'H+5%~ _ХH,UCꉕDQG[.vH+^}iV/7,YICڹtUEk3E=JC z=UOj#>I>욖Ezg ;ぇgמfU~7sI>w-}=,C9!B1 4 !BAI!B MB!b8hB!!B1M|E%g||N Н$8Y)%еv,#wT=6@7 {D ս;!, o31i&mTv:;_K3YTl-tfu+qIT%N|^*I88AL|p!=^A[^MwLPvy+Nj{\]7f~xT|K3#okfb"-[_!ÂBw>$ ӧrņ;|^̰WҮ]Z5m~FVBW6FZiy*-%fi' be>t;uamv\u{į !BaI!B MB!b8hB!AB!!BAh:=jGK#t뺎ȽUD͒w@Ѥ]j:B0"Bc4Iٍ>.>8%}^.sZVGKM_s'Z{v_b<Nj\ZթGsNٞRܩpA'-2K+.g526NT~sY6+6^]/ZfN%YU;gc ]BDtˁ?"e?t+SK9jike-'K\Aq)]]kj;tg,KKѪ@/>uQgD bJENg. UX6~m{*w?θۯ~rt9ceCw@7AMǁR=o} ]ә))ݡ5e´Ŀo,t)aKY^"wnRaCLFڹt!*s~ 3L^n3T"tsj:D/]vw]oWB!0p$B!&!B14 !BAI!B FB! 4knT.) R6 t? R-Lb953C27tfȽ#u &F[=+.).ށnZjIK 89oO5S>:SjN4tN$/NpګK3I}FZgtKK]w躗ߑ78MbDM-9']5{I|SlB’][s_gs+WH:%ۿlYݒyB6H8S䏋dHlui/z-%Bg==MU[1˜P&˴spyܩƌ S{4P~ޛ?/ |·[ swIO]eWU13܀njq/m=:f275qR9t.oSKkԍvнzb%֪癵]"tUAt.j]KIq~Qlfٙ8F3vv:;_YB}[f>Uϥa;水|:::'B!&!B14 !BAI!B MB!b7"B!r\)4f;JiW=:_m]ւ~5m^+p ţIK1'Ȏn8s3d5M2 t5&-9`P] {5q,--﬩>NÆAyٴv8tKV۝qǃvjB{Fk>.c_jN¥9tvտhCPo."e_ХH-8Ӑ$8˲Xl4k5]]ݟЕfn>ҞQfYEA'a+],_@lY<Gdxv] 8-ЅK6|,Js|8]uo_i32"=rG2t6dHtrf~N,=+9 /%SlnOSZ0Wy\C^r5gǹˢ=G=fyK5ӳn+W ݰK@/}JeL.@rCÂBw>XTIϢF8>Kn'C#(E漟ϒ.K._A{5#b9<䎳%9R?'e9:-^ȈUۡ;fv_loθDy]3yk ]Fgt gt]'R[6ooZNJ+w0SS(ZVE(Z)pAR_|:SQ;{xt#巠 YGj*0(Yg%+WHNifImk2n*m^Y[W52/!;SEUzT "aݗX݉Ys6RY ]ߐ$w "6L|xyYd|NULjf ݛ85s:/jF,ZZfߓQuߚCא枘.ϝ2cE -ߡ>[m4_ ]h5A:fѾǶi!t'VUZG tm4 gqcƧ=<:,P?δܞB!B! p$B!&!B14 !BA`ވB!Zǹ3tE7$6p!taI%΁|^*}cK) -.-nйf9Ay]%E|Ux^nj}'-1z.V?6WG^ݾ$AvJqt{ln@2Prd5vkVUYVSR2trh թdG7w5.X;蚚0R?prU;T&;ǁr5'q)gLi v}ZZmН2 RPlE7iɖ[A7oAYS7Ε8GlCKef7 531Q3Ax ix^rX'w@7gԙάn Ivb@v?tImos20:>sQJm,^RiœN+Z`(2>憴]+\>myk ]Fyi$-E3h t$tE[tK:]2l`t N4eRsXZ.cĪН]@b U>;FA>ttSYCfJc d( %99X6;;AXz.jꥭqf- @k;5 qdНTMiIЙ:Rls>v275qYaς깒:/"Vndv#\@S0]Upy^~j{t<q"mjryt6ţ貯VS`Wk of´ݟ )AG@gz_*Uq~k^ 9%~WMqdmjI6?Kf*t9˅x>e:Kǹ˾!%N4H9!B1 4 !BAI!B MB!b8hB!!B1Fyw; *s })y]35e 22TMiu R tV!#ť9tv|kenm|Wh%Ͷʐ1mx,l3۞JV=|aGRNfɍs6.߂.d4$ t7u7Z=,̆n}4ǿgm}:KZVaе?^M-lזe$gREEO4PDR \]X6 'Mߝ,>+q$}|yLf̶Ȅn+/5t!*}cK) SSg.$E-^Ku+}efvݾeċ%fCg6nzh,mh_3nF..z&;^]ѧ.j~KZ\1NP w)3qj 7K.#-s0}d<tGZentKBKe%tkcW;k1trI|rWAF>~S˾vX+ V3>'ӱ3_]ZC>9,]߫'z:94],,,zꕤg$7ʝKu&TsI{~ZJ\ϗM7)tj ̥ kKЭOsHUmoj絖S@iqɷ]+:ՔώQХ?-U~a-Ci ?{ɴ>8cw^iѢt/_ )?Tii!csB!b8hB!AB!B! p$B!y#B!b&)fւ~aUCWZ9tvLCB}[f> gt ݩ{?Ax ĉ ˤ1r54qR;#2Vf(v.pw)tCmqLj&ct:;XQB~q_ep]vI]gZе_5Lͫ|KjO5U :)ν+QC8b;BKF,q2T~  d[Ѕ\eX&H {$f~xTuqzGP*M: j֣$dN|?3YWsLËЅW#v9W3UdE;{m^*fث5ЅT4~R`Z:N{+ZCUrlxgŀ\5Dt:&>%}}'4H_ֵWZ- BmFL;=.?W tV!#iyt}}dT/t>PS|e9%B!B! p$B!&!B14 !BA`ވB!kAs"C1mXX2d^v?/ IOO^]v\h_]c[5"tCԜK_謧ɛ蚙y#-)ԋv Zg!7Εm LҚ[Uͫh]{Z&e-m%=_3>sCYRq̟t9"8$+*w$Cg3?@)&k~U]S3LZ^E˝hZKBMPfkSgԍ)8T~x鸜geke-'t^˚ ٸ=>x&Qе|)[ϴ=ŦKs*V9Y8K6.`}:vZ=zNSY$U8E-+r~f|}4O$5Y`T֚s~e}7wpҩU-t_T}:]#)x;Y+ E2dL.|yKZQ;N:1N^i'-w.WB!0p$B!&!B14 !BAI!B FB! fgP}}T?UHIo ӧ2.7~nuiY ߡ{F..ꊼp9IH(^O{J_b>*ʢ=趚B/%SM5]T_'t~,{;2[ғgAWfXCQ&T\`52,sf|0VZ{˗2p^y Z*VeNEl(/ Y,ʠaf{VvtK^KA$:jBE[gӒe3p)X}:ۖR;j.μ&55? gwDz]K5N8Odt \UX6,rQ{<}bӲkK,q]ݦԟG僺R'lН[v-Q\m )??"] ) self.assertEqual(public_item.source, public_source) # Make sure that an item can still access its related source even if the default # manager doesn't normally allow it. self.assertEqual(private_item.source, private_source) # If the manager is marked "use_for_related_fields", it'll get used instead # of the "bare" queryset. Usually you'd define this as a property on the class, # but this approximates that in a way that's easier in tests. Source.objects.use_for_related_fields = True private_item = Item.objects.get(pk=private_item.pk) self.assertRaises(Source.DoesNotExist, lambda: private_item.source) Django-1.6.11/tests/reverse_single_related/models.py0000664000175000017500000000054012502407523022122 0ustar timtim00000000000000from django.db import models class SourceManager(models.Manager): def get_queryset(self): return super(SourceManager, self).get_queryset().filter(is_public=True) class Source(models.Model): is_public = models.BooleanField(default=False) objects = SourceManager() class Item(models.Model): source = models.ForeignKey(Source) Django-1.6.11/tests/.coveragerc0000664000175000017500000000041612502407523015674 0ustar timtim00000000000000[run] omit = */django/contrib/*/tests*,*/django/utils/unittest*,*/django/utils/simplejson*,*/django/utils/importlib.py,*/django/test/_doctest.py,*/django/core/servers/fastcgi.py,*/django/utils/autoreload.py,*/django/utils/dictconfig.py [html] directory = coverage_html Django-1.6.11/tests/model_validation/0000775000175000017500000000000012502407547017072 5ustar timtim00000000000000Django-1.6.11/tests/model_validation/__init__.py0000664000175000017500000000000012477341424021173 0ustar timtim00000000000000Django-1.6.11/tests/model_validation/tests.py0000664000175000017500000000065412502407523020605 0ustar timtim00000000000000from django.core import management from django.test import TestCase from django.utils import six class ModelValidationTest(TestCase): def test_models_validate(self): # All our models should validate properly # Validation Tests: # * choices= Iterable of Iterables # See: https://code.djangoproject.com/ticket/20430 management.call_command("validate", stdout=six.StringIO()) Django-1.6.11/tests/model_validation/models.py0000664000175000017500000000114612502407523020723 0ustar timtim00000000000000from django.db import models class ThingItem(object): def __init__(self, value, display): self.value = value self.display = display def __iter__(self): return (x for x in [self.value, self.display]) def __len__(self): return 2 class Things(object): def __iter__(self): return (x for x in [ThingItem(1, 2), ThingItem(3, 4)]) class ThingWithIterableChoices(models.Model): # Testing choices= Iterable of Iterables # See: https://code.djangoproject.com/ticket/20430 thing = models.CharField(max_length=100, blank=True, choices=Things()) Django-1.6.11/tests/queryset_pickle/0000775000175000017500000000000012502407547016770 5ustar timtim00000000000000Django-1.6.11/tests/queryset_pickle/__init__.py0000664000175000017500000000000012477341424021071 0ustar timtim00000000000000Django-1.6.11/tests/queryset_pickle/tests.py0000664000175000017500000000742212502407523020503 0ustar timtim00000000000000from __future__ import absolute_import import pickle import datetime from django.db import models from django.test import TestCase from .models import Group, Event, Happening, Container, M2MModel class PickleabilityTestCase(TestCase): def setUp(self): Happening.objects.create() # make sure the defaults are working (#20158) def assert_pickles(self, qs): self.assertEqual(list(pickle.loads(pickle.dumps(qs))), list(qs)) def test_related_field(self): g = Group.objects.create(name="Ponies Who Own Maybachs") self.assert_pickles(Event.objects.filter(group=g.id)) def test_datetime_callable_default_all(self): self.assert_pickles(Happening.objects.all()) def test_datetime_callable_default_filter(self): self.assert_pickles(Happening.objects.filter(when=datetime.datetime.now())) def test_lambda_as_default(self): self.assert_pickles(Happening.objects.filter(name="test")) def test_standalone_method_as_default(self): self.assert_pickles(Happening.objects.filter(number1=1)) def test_staticmethod_as_default(self): self.assert_pickles(Happening.objects.filter(number2=1)) def test_classmethod_as_default(self): self.assert_pickles(Happening.objects.filter(number3=1)) def test_membermethod_as_default(self): self.assert_pickles(Happening.objects.filter(number4=1)) def test_doesnotexist_exception(self): # Ticket #17776 original = Event.DoesNotExist("Doesn't exist") unpickled = pickle.loads(pickle.dumps(original)) # Exceptions are not equal to equivalent instances of themselves, so # can't just use assertEqual(original, unpickled) self.assertEqual(original.__class__, unpickled.__class__) self.assertEqual(original.args, unpickled.args) def test_model_pickle(self): """ Test that a model not defined on module level is pickleable. """ original = Container.SomeModel(pk=1) dumped = pickle.dumps(original) reloaded = pickle.loads(dumped) self.assertEqual(original, reloaded) # Also, deferred dynamic model works Container.SomeModel.objects.create(somefield=1) original = Container.SomeModel.objects.defer('somefield')[0] dumped = pickle.dumps(original) reloaded = pickle.loads(dumped) self.assertEqual(original, reloaded) self.assertEqual(original.somefield, reloaded.somefield) def test_model_pickle_m2m(self): """ Test intentionally the automatically created through model. """ m1 = M2MModel.objects.create() g1 = Group.objects.create(name='foof') m1.groups.add(g1) m2m_through = M2MModel._meta.get_field_by_name('groups')[0].rel.through original = m2m_through.objects.get() dumped = pickle.dumps(original) reloaded = pickle.loads(dumped) self.assertEqual(original, reloaded) def test_model_pickle_dynamic(self): class Meta: proxy = True dynclass = type("DynamicEventSubclass", (Event, ), {'Meta': Meta, '__module__': Event.__module__}) original = dynclass(pk=1) dumped = pickle.dumps(original) reloaded = pickle.loads(dumped) self.assertEqual(original, reloaded) self.assertIs(reloaded.__class__, dynclass) def test_pickle_prefetch_related_idempotence(self): g = Group.objects.create(name='foo') groups = Group.objects.prefetch_related('event_set') # First pickling groups = pickle.loads(pickle.dumps(groups)) self.assertQuerysetEqual(groups, [g], lambda x: x) # Second pickling groups = pickle.loads(pickle.dumps(groups)) self.assertQuerysetEqual(groups, [g], lambda x: x) Django-1.6.11/tests/queryset_pickle/models.py0000664000175000017500000000260012502407523020615 0ustar timtim00000000000000from __future__ import absolute_import import datetime from django.db import models from django.utils.translation import ugettext_lazy as _ def standalone_number(): return 1 class Numbers(object): @staticmethod def get_static_number(): return 2 @classmethod def get_class_number(cls): return 3 def get_member_number(self): return 4 nn = Numbers() class Group(models.Model): name = models.CharField(_('name'), max_length=100) class Event(models.Model): group = models.ForeignKey(Group) class Happening(models.Model): when = models.DateTimeField(blank=True, default=datetime.datetime.now) name = models.CharField(blank=True, max_length=100, default=lambda:"test") number1 = models.IntegerField(blank=True, default=standalone_number) number2 = models.IntegerField(blank=True, default=Numbers.get_static_number) number3 = models.IntegerField(blank=True, default=Numbers.get_class_number) number4 = models.IntegerField(blank=True, default=nn.get_member_number) class Container(object): # To test pickling we need a class that isn't defined on module, but # is still available from app-cache. So, the Container class moves # SomeModel outside of module level class SomeModel(models.Model): somefield = models.IntegerField() class M2MModel(models.Model): groups = models.ManyToManyField(Group) Django-1.6.11/tests/mutually_referential/0000775000175000017500000000000012502407547020014 5ustar timtim00000000000000Django-1.6.11/tests/mutually_referential/__init__.py0000664000175000017500000000000012477341424022115 0ustar timtim00000000000000Django-1.6.11/tests/mutually_referential/tests.py0000664000175000017500000000111212502407523021515 0ustar timtim00000000000000from __future__ import absolute_import from django.test import TestCase from .models import Parent class MutuallyReferentialTests(TestCase): def test_mutually_referential(self): # Create a Parent q = Parent(name='Elizabeth') q.save() # Create some children c = q.child_set.create(name='Charles') e = q.child_set.create(name='Edward') # Set the best child # No assertion require here; if basic assignment and # deletion works, the test passes. q.bestchild = c q.save() q.delete() Django-1.6.11/tests/mutually_referential/models.py0000664000175000017500000000106512502407523021645 0ustar timtim00000000000000""" 24. Mutually referential many-to-one relationships Strings can be used instead of model literals to set up "lazy" relations. """ from django.db import models class Parent(models.Model): name = models.CharField(max_length=100) # Use a simple string for forward declarations. bestchild = models.ForeignKey("Child", null=True, related_name="favoured_by") class Child(models.Model): name = models.CharField(max_length=100) # You can also explicitally specify the related app. parent = models.ForeignKey("mutually_referential.Parent") Django-1.6.11/tests/dates/0000775000175000017500000000000012502407547014660 5ustar timtim00000000000000Django-1.6.11/tests/dates/__init__.py0000664000175000017500000000000012477341424016761 0ustar timtim00000000000000Django-1.6.11/tests/dates/tests.py0000664000175000017500000000471412502407523016374 0ustar timtim00000000000000from __future__ import absolute_import import datetime from django.test import TestCase from .models import Article, Comment, Category class DatesTests(TestCase): def test_related_model_traverse(self): a1 = Article.objects.create( title="First one", pub_date=datetime.date(2005, 7, 28), ) a2 = Article.objects.create( title="Another one", pub_date=datetime.date(2010, 7, 28), ) a3 = Article.objects.create( title="Third one, in the first day", pub_date=datetime.date(2005, 7, 28), ) a1.comments.create( text="Im the HULK!", pub_date=datetime.date(2005, 7, 28), ) a1.comments.create( text="HULK SMASH!", pub_date=datetime.date(2005, 7, 29), ) a2.comments.create( text="LMAO", pub_date=datetime.date(2010, 7, 28), ) a3.comments.create( text="+1", pub_date=datetime.date(2005, 8, 29), ) c = Category.objects.create(name="serious-news") c.articles.add(a1, a3) self.assertQuerysetEqual( Comment.objects.dates("article__pub_date", "year"), [ datetime.date(2005, 1, 1), datetime.date(2010, 1, 1), ], lambda d: d, ) self.assertQuerysetEqual( Comment.objects.dates("article__pub_date", "month"), [ datetime.date(2005, 7, 1), datetime.date(2010, 7, 1), ], lambda d: d ) self.assertQuerysetEqual( Comment.objects.dates("article__pub_date", "day"), [ datetime.date(2005, 7, 28), datetime.date(2010, 7, 28), ], lambda d: d ) self.assertQuerysetEqual( Article.objects.dates("comments__pub_date", "day"), [ datetime.date(2005, 7, 28), datetime.date(2005, 7, 29), datetime.date(2005, 8, 29), datetime.date(2010, 7, 28), ], lambda d: d ) self.assertQuerysetEqual( Article.objects.dates("comments__approval_date", "day"), [] ) self.assertQuerysetEqual( Category.objects.dates("articles__pub_date", "day"), [ datetime.date(2005, 7, 28), ], lambda d: d, ) Django-1.6.11/tests/dates/models.py0000664000175000017500000000145112502407523016510 0ustar timtim00000000000000from __future__ import unicode_literals from django.db import models from django.utils.encoding import python_2_unicode_compatible @python_2_unicode_compatible class Article(models.Model): title = models.CharField(max_length=100) pub_date = models.DateField() categories = models.ManyToManyField("Category", related_name="articles") def __str__(self): return self.title @python_2_unicode_compatible class Comment(models.Model): article = models.ForeignKey(Article, related_name="comments") text = models.TextField() pub_date = models.DateField() approval_date = models.DateField(null=True) def __str__(self): return 'Comment to %s (%s)' % (self.article.title, self.pub_date) class Category(models.Model): name = models.CharField(max_length=255) Django-1.6.11/tests/admin_filters/0000775000175000017500000000000012502407547016400 5ustar timtim00000000000000Django-1.6.11/tests/admin_filters/__init__.py0000664000175000017500000000000012477341424020501 0ustar timtim00000000000000Django-1.6.11/tests/admin_filters/tests.py0000664000175000017500000010525312502407523020114 0ustar timtim00000000000000from __future__ import absolute_import, unicode_literals import datetime from django.contrib.admin import (site, ModelAdmin, SimpleListFilter, BooleanFieldListFilter) from django.contrib.admin.views.main import ChangeList from django.contrib.auth.admin import UserAdmin from django.contrib.auth.models import User from django.core.exceptions import ImproperlyConfigured from django.test import TestCase, RequestFactory from django.test.utils import override_settings, six from django.utils.encoding import force_text from .models import Book, Department, Employee def select_by(dictlist, key, value): return [x for x in dictlist if x[key] == value][0] class DecadeListFilter(SimpleListFilter): def lookups(self, request, model_admin): return ( ('the 80s', "the 1980's"), ('the 90s', "the 1990's"), ('the 00s', "the 2000's"), ('other', "other decades"), ) def queryset(self, request, queryset): decade = self.value() if decade == 'the 80s': return queryset.filter(year__gte=1980, year__lte=1989) if decade == 'the 90s': return queryset.filter(year__gte=1990, year__lte=1999) if decade == 'the 00s': return queryset.filter(year__gte=2000, year__lte=2009) class DecadeListFilterWithTitleAndParameter(DecadeListFilter): title = 'publication decade' parameter_name = 'publication-decade' class DecadeListFilterWithoutTitle(DecadeListFilter): parameter_name = 'publication-decade' class DecadeListFilterWithoutParameter(DecadeListFilter): title = 'publication decade' class DecadeListFilterWithNoneReturningLookups(DecadeListFilterWithTitleAndParameter): def lookups(self, request, model_admin): pass class DecadeListFilterWithFailingQueryset(DecadeListFilterWithTitleAndParameter): def queryset(self, request, queryset): raise 1/0 class DecadeListFilterWithQuerysetBasedLookups(DecadeListFilterWithTitleAndParameter): def lookups(self, request, model_admin): qs = model_admin.get_queryset(request) if qs.filter(year__gte=1980, year__lte=1989).exists(): yield ('the 80s', "the 1980's") if qs.filter(year__gte=1990, year__lte=1999).exists(): yield ('the 90s', "the 1990's") if qs.filter(year__gte=2000, year__lte=2009).exists(): yield ('the 00s', "the 2000's") class DecadeListFilterParameterEndsWith__In(DecadeListFilter): title = 'publication decade' parameter_name = 'decade__in' # Ends with '__in" class DecadeListFilterParameterEndsWith__Isnull(DecadeListFilter): title = 'publication decade' parameter_name = 'decade__isnull' # Ends with '__isnull" class DepartmentListFilterLookupWithNonStringValue(SimpleListFilter): title = 'department' parameter_name = 'department' def lookups(self, request, model_admin): return sorted(set([ (employee.department.id, # Intentionally not a string (Refs #19318) employee.department.code) for employee in model_admin.get_queryset(request).all() ])) def queryset(self, request, queryset): if self.value(): return queryset.filter(department__id=self.value()) class CustomUserAdmin(UserAdmin): list_filter = ('books_authored', 'books_contributed') class BookAdmin(ModelAdmin): list_filter = ('year', 'author', 'contributors', 'is_best_seller', 'date_registered', 'no') ordering = ('-id',) class BookAdminWithTupleBooleanFilter(BookAdmin): list_filter = ('year', 'author', 'contributors', ('is_best_seller', BooleanFieldListFilter), 'date_registered', 'no') class DecadeFilterBookAdmin(ModelAdmin): list_filter = ('author', DecadeListFilterWithTitleAndParameter) ordering = ('-id',) class DecadeFilterBookAdminWithoutTitle(ModelAdmin): list_filter = (DecadeListFilterWithoutTitle,) class DecadeFilterBookAdminWithoutParameter(ModelAdmin): list_filter = (DecadeListFilterWithoutParameter,) class DecadeFilterBookAdminWithNoneReturningLookups(ModelAdmin): list_filter = (DecadeListFilterWithNoneReturningLookups,) class DecadeFilterBookAdminWithFailingQueryset(ModelAdmin): list_filter = (DecadeListFilterWithFailingQueryset,) class DecadeFilterBookAdminWithQuerysetBasedLookups(ModelAdmin): list_filter = (DecadeListFilterWithQuerysetBasedLookups,) class DecadeFilterBookAdminParameterEndsWith__In(ModelAdmin): list_filter = (DecadeListFilterParameterEndsWith__In,) class DecadeFilterBookAdminParameterEndsWith__Isnull(ModelAdmin): list_filter = (DecadeListFilterParameterEndsWith__Isnull,) class EmployeeAdmin(ModelAdmin): list_display = ['name', 'department'] list_filter = ['department'] class DepartmentFilterEmployeeAdmin(EmployeeAdmin): list_filter = [DepartmentListFilterLookupWithNonStringValue, ] class ListFiltersTests(TestCase): def setUp(self): self.today = datetime.date.today() self.tomorrow = self.today + datetime.timedelta(days=1) self.one_week_ago = self.today - datetime.timedelta(days=7) if self.today.month == 12: self.next_month = self.today.replace(year=self.today.year + 1, month=1, day=1) else: self.next_month = self.today.replace(month=self.today.month + 1, day=1) self.next_year = self.today.replace(year=self.today.year + 1, month=1, day=1) self.request_factory = RequestFactory() # Users self.alfred = User.objects.create_user('alfred', 'alfred@example.com') self.bob = User.objects.create_user('bob', 'bob@example.com') self.lisa = User.objects.create_user('lisa', 'lisa@example.com') # Books self.djangonaut_book = Book.objects.create(title='Djangonaut: an art of living', year=2009, author=self.alfred, is_best_seller=True, date_registered=self.today) self.bio_book = Book.objects.create(title='Django: a biography', year=1999, author=self.alfred, is_best_seller=False, no=207) self.django_book = Book.objects.create(title='The Django Book', year=None, author=self.bob, is_best_seller=None, date_registered=self.today, no=103) self.gipsy_book = Book.objects.create(title='Gipsy guitar for dummies', year=2002, is_best_seller=True, date_registered=self.one_week_ago) self.gipsy_book.contributors = [self.bob, self.lisa] self.gipsy_book.save() # Departments self.dev = Department.objects.create(code='DEV', description='Development') self.design = Department.objects.create(code='DSN', description='Design') # Employees self.john = Employee.objects.create(name='John Blue', department=self.dev) self.jack = Employee.objects.create(name='Jack Red', department=self.design) def get_changelist(self, request, model, modeladmin): return ChangeList(request, model, modeladmin.list_display, modeladmin.list_display_links, modeladmin.list_filter, modeladmin.date_hierarchy, modeladmin.search_fields, modeladmin.list_select_related, modeladmin.list_per_page, modeladmin.list_max_show_all, modeladmin.list_editable, modeladmin) def test_datefieldlistfilter(self): modeladmin = BookAdmin(Book, site) request = self.request_factory.get('/') changelist = self.get_changelist(request, Book, modeladmin) request = self.request_factory.get('/', {'date_registered__gte': self.today, 'date_registered__lt': self.tomorrow}) changelist = self.get_changelist(request, Book, modeladmin) # Make sure the correct queryset is returned queryset = changelist.get_queryset(request) self.assertEqual(list(queryset), [self.django_book, self.djangonaut_book]) # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][4] self.assertEqual(force_text(filterspec.title), 'date registered') choice = select_by(filterspec.choices(changelist), "display", "Today") self.assertEqual(choice['selected'], True) self.assertEqual(choice['query_string'], '?date_registered__gte=%s' '&date_registered__lt=%s' % (self.today, self.tomorrow)) request = self.request_factory.get('/', {'date_registered__gte': self.today.replace(day=1), 'date_registered__lt': self.next_month}) changelist = self.get_changelist(request, Book, modeladmin) # Make sure the correct queryset is returned queryset = changelist.get_queryset(request) if (self.today.year, self.today.month) == (self.one_week_ago.year, self.one_week_ago.month): # In case one week ago is in the same month. self.assertEqual(list(queryset), [self.gipsy_book, self.django_book, self.djangonaut_book]) else: self.assertEqual(list(queryset), [self.django_book, self.djangonaut_book]) # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][4] self.assertEqual(force_text(filterspec.title), 'date registered') choice = select_by(filterspec.choices(changelist), "display", "This month") self.assertEqual(choice['selected'], True) self.assertEqual(choice['query_string'], '?date_registered__gte=%s' '&date_registered__lt=%s' % (self.today.replace(day=1), self.next_month)) request = self.request_factory.get('/', {'date_registered__gte': self.today.replace(month=1, day=1), 'date_registered__lt': self.next_year}) changelist = self.get_changelist(request, Book, modeladmin) # Make sure the correct queryset is returned queryset = changelist.get_queryset(request) if self.today.year == self.one_week_ago.year: # In case one week ago is in the same year. self.assertEqual(list(queryset), [self.gipsy_book, self.django_book, self.djangonaut_book]) else: self.assertEqual(list(queryset), [self.django_book, self.djangonaut_book]) # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][4] self.assertEqual(force_text(filterspec.title), 'date registered') choice = select_by(filterspec.choices(changelist), "display", "This year") self.assertEqual(choice['selected'], True) self.assertEqual(choice['query_string'], '?date_registered__gte=%s' '&date_registered__lt=%s' % (self.today.replace(month=1, day=1), self.next_year)) request = self.request_factory.get('/', {'date_registered__gte': str(self.one_week_ago), 'date_registered__lt': str(self.tomorrow)}) changelist = self.get_changelist(request, Book, modeladmin) # Make sure the correct queryset is returned queryset = changelist.get_queryset(request) self.assertEqual(list(queryset), [self.gipsy_book, self.django_book, self.djangonaut_book]) # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][4] self.assertEqual(force_text(filterspec.title), 'date registered') choice = select_by(filterspec.choices(changelist), "display", "Past 7 days") self.assertEqual(choice['selected'], True) self.assertEqual(choice['query_string'], '?date_registered__gte=%s' '&date_registered__lt=%s' % (str(self.one_week_ago), str(self.tomorrow))) @override_settings(USE_TZ=True) def test_datefieldlistfilter_with_time_zone_support(self): # Regression for #17830 self.test_datefieldlistfilter() def test_allvaluesfieldlistfilter(self): modeladmin = BookAdmin(Book, site) request = self.request_factory.get('/', {'year__isnull': 'True'}) changelist = self.get_changelist(request, Book, modeladmin) # Make sure the correct queryset is returned queryset = changelist.get_queryset(request) self.assertEqual(list(queryset), [self.django_book]) # Make sure the last choice is None and is selected filterspec = changelist.get_filters(request)[0][0] self.assertEqual(force_text(filterspec.title), 'year') choices = list(filterspec.choices(changelist)) self.assertEqual(choices[-1]['selected'], True) self.assertEqual(choices[-1]['query_string'], '?year__isnull=True') request = self.request_factory.get('/', {'year': '2002'}) changelist = self.get_changelist(request, Book, modeladmin) # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][0] self.assertEqual(force_text(filterspec.title), 'year') choices = list(filterspec.choices(changelist)) self.assertEqual(choices[2]['selected'], True) self.assertEqual(choices[2]['query_string'], '?year=2002') def test_relatedfieldlistfilter_foreignkey(self): modeladmin = BookAdmin(Book, site) request = self.request_factory.get('/', {'author__isnull': 'True'}) changelist = self.get_changelist(request, Book, modeladmin) # Make sure the correct queryset is returned queryset = changelist.get_queryset(request) self.assertEqual(list(queryset), [self.gipsy_book]) # Make sure the last choice is None and is selected filterspec = changelist.get_filters(request)[0][1] self.assertEqual(force_text(filterspec.title), 'Verbose Author') choices = list(filterspec.choices(changelist)) self.assertEqual(choices[-1]['selected'], True) self.assertEqual(choices[-1]['query_string'], '?author__isnull=True') request = self.request_factory.get('/', {'author__id__exact': self.alfred.pk}) changelist = self.get_changelist(request, Book, modeladmin) # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][1] self.assertEqual(force_text(filterspec.title), 'Verbose Author') # order of choices depends on User model, which has no order choice = select_by(filterspec.choices(changelist), "display", "alfred") self.assertEqual(choice['selected'], True) self.assertEqual(choice['query_string'], '?author__id__exact=%d' % self.alfred.pk) def test_relatedfieldlistfilter_manytomany(self): modeladmin = BookAdmin(Book, site) request = self.request_factory.get('/', {'contributors__isnull': 'True'}) changelist = self.get_changelist(request, Book, modeladmin) # Make sure the correct queryset is returned queryset = changelist.get_queryset(request) self.assertEqual(list(queryset), [self.django_book, self.bio_book, self.djangonaut_book]) # Make sure the last choice is None and is selected filterspec = changelist.get_filters(request)[0][2] self.assertEqual(force_text(filterspec.title), 'Verbose Contributors') choices = list(filterspec.choices(changelist)) self.assertEqual(choices[-1]['selected'], True) self.assertEqual(choices[-1]['query_string'], '?contributors__isnull=True') request = self.request_factory.get('/', {'contributors__id__exact': self.bob.pk}) changelist = self.get_changelist(request, Book, modeladmin) # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][2] self.assertEqual(force_text(filterspec.title), 'Verbose Contributors') choice = select_by(filterspec.choices(changelist), "display", "bob") self.assertEqual(choice['selected'], True) self.assertEqual(choice['query_string'], '?contributors__id__exact=%d' % self.bob.pk) def test_relatedfieldlistfilter_reverse_relationships(self): modeladmin = CustomUserAdmin(User, site) # FK relationship ----- request = self.request_factory.get('/', {'books_authored__isnull': 'True'}) changelist = self.get_changelist(request, User, modeladmin) # Make sure the correct queryset is returned queryset = changelist.get_queryset(request) self.assertEqual(list(queryset), [self.lisa]) # Make sure the last choice is None and is selected filterspec = changelist.get_filters(request)[0][0] self.assertEqual(force_text(filterspec.title), 'book') choices = list(filterspec.choices(changelist)) self.assertEqual(choices[-1]['selected'], True) self.assertEqual(choices[-1]['query_string'], '?books_authored__isnull=True') request = self.request_factory.get('/', {'books_authored__id__exact': self.bio_book.pk}) changelist = self.get_changelist(request, User, modeladmin) # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][0] self.assertEqual(force_text(filterspec.title), 'book') choice = select_by(filterspec.choices(changelist), "display", self.bio_book.title) self.assertEqual(choice['selected'], True) self.assertEqual(choice['query_string'], '?books_authored__id__exact=%d' % self.bio_book.pk) # M2M relationship ----- request = self.request_factory.get('/', {'books_contributed__isnull': 'True'}) changelist = self.get_changelist(request, User, modeladmin) # Make sure the correct queryset is returned queryset = changelist.get_queryset(request) self.assertEqual(list(queryset), [self.alfred]) # Make sure the last choice is None and is selected filterspec = changelist.get_filters(request)[0][1] self.assertEqual(force_text(filterspec.title), 'book') choices = list(filterspec.choices(changelist)) self.assertEqual(choices[-1]['selected'], True) self.assertEqual(choices[-1]['query_string'], '?books_contributed__isnull=True') request = self.request_factory.get('/', {'books_contributed__id__exact': self.django_book.pk}) changelist = self.get_changelist(request, User, modeladmin) # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][1] self.assertEqual(force_text(filterspec.title), 'book') choice = select_by(filterspec.choices(changelist), "display", self.django_book.title) self.assertEqual(choice['selected'], True) self.assertEqual(choice['query_string'], '?books_contributed__id__exact=%d' % self.django_book.pk) def test_booleanfieldlistfilter(self): modeladmin = BookAdmin(Book, site) self.verify_booleanfieldlistfilter(modeladmin) def test_booleanfieldlistfilter_tuple(self): modeladmin = BookAdminWithTupleBooleanFilter(Book, site) self.verify_booleanfieldlistfilter(modeladmin) def verify_booleanfieldlistfilter(self, modeladmin): request = self.request_factory.get('/') changelist = self.get_changelist(request, Book, modeladmin) request = self.request_factory.get('/', {'is_best_seller__exact': 0}) changelist = self.get_changelist(request, Book, modeladmin) # Make sure the correct queryset is returned queryset = changelist.get_queryset(request) self.assertEqual(list(queryset), [self.bio_book]) # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][3] self.assertEqual(force_text(filterspec.title), 'is best seller') choice = select_by(filterspec.choices(changelist), "display", "No") self.assertEqual(choice['selected'], True) self.assertEqual(choice['query_string'], '?is_best_seller__exact=0') request = self.request_factory.get('/', {'is_best_seller__exact': 1}) changelist = self.get_changelist(request, Book, modeladmin) # Make sure the correct queryset is returned queryset = changelist.get_queryset(request) self.assertEqual(list(queryset), [self.gipsy_book, self.djangonaut_book]) # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][3] self.assertEqual(force_text(filterspec.title), 'is best seller') choice = select_by(filterspec.choices(changelist), "display", "Yes") self.assertEqual(choice['selected'], True) self.assertEqual(choice['query_string'], '?is_best_seller__exact=1') request = self.request_factory.get('/', {'is_best_seller__isnull': 'True'}) changelist = self.get_changelist(request, Book, modeladmin) # Make sure the correct queryset is returned queryset = changelist.get_queryset(request) self.assertEqual(list(queryset), [self.django_book]) # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][3] self.assertEqual(force_text(filterspec.title), 'is best seller') choice = select_by(filterspec.choices(changelist), "display", "Unknown") self.assertEqual(choice['selected'], True) self.assertEqual(choice['query_string'], '?is_best_seller__isnull=True') def test_simplelistfilter(self): modeladmin = DecadeFilterBookAdmin(Book, site) # Make sure that the first option is 'All' --------------------------- request = self.request_factory.get('/', {}) changelist = self.get_changelist(request, Book, modeladmin) # Make sure the correct queryset is returned queryset = changelist.get_queryset(request) self.assertEqual(list(queryset), list(Book.objects.all().order_by('-id'))) # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][1] self.assertEqual(force_text(filterspec.title), 'publication decade') choices = list(filterspec.choices(changelist)) self.assertEqual(choices[0]['display'], 'All') self.assertEqual(choices[0]['selected'], True) self.assertEqual(choices[0]['query_string'], '?') # Look for books in the 1980s ---------------------------------------- request = self.request_factory.get('/', {'publication-decade': 'the 80s'}) changelist = self.get_changelist(request, Book, modeladmin) # Make sure the correct queryset is returned queryset = changelist.get_queryset(request) self.assertEqual(list(queryset), []) # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][1] self.assertEqual(force_text(filterspec.title), 'publication decade') choices = list(filterspec.choices(changelist)) self.assertEqual(choices[1]['display'], 'the 1980\'s') self.assertEqual(choices[1]['selected'], True) self.assertEqual(choices[1]['query_string'], '?publication-decade=the+80s') # Look for books in the 1990s ---------------------------------------- request = self.request_factory.get('/', {'publication-decade': 'the 90s'}) changelist = self.get_changelist(request, Book, modeladmin) # Make sure the correct queryset is returned queryset = changelist.get_queryset(request) self.assertEqual(list(queryset), [self.bio_book]) # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][1] self.assertEqual(force_text(filterspec.title), 'publication decade') choices = list(filterspec.choices(changelist)) self.assertEqual(choices[2]['display'], 'the 1990\'s') self.assertEqual(choices[2]['selected'], True) self.assertEqual(choices[2]['query_string'], '?publication-decade=the+90s') # Look for books in the 2000s ---------------------------------------- request = self.request_factory.get('/', {'publication-decade': 'the 00s'}) changelist = self.get_changelist(request, Book, modeladmin) # Make sure the correct queryset is returned queryset = changelist.get_queryset(request) self.assertEqual(list(queryset), [self.gipsy_book, self.djangonaut_book]) # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][1] self.assertEqual(force_text(filterspec.title), 'publication decade') choices = list(filterspec.choices(changelist)) self.assertEqual(choices[3]['display'], 'the 2000\'s') self.assertEqual(choices[3]['selected'], True) self.assertEqual(choices[3]['query_string'], '?publication-decade=the+00s') # Combine multiple filters ------------------------------------------- request = self.request_factory.get('/', {'publication-decade': 'the 00s', 'author__id__exact': self.alfred.pk}) changelist = self.get_changelist(request, Book, modeladmin) # Make sure the correct queryset is returned queryset = changelist.get_queryset(request) self.assertEqual(list(queryset), [self.djangonaut_book]) # Make sure the correct choices are selected filterspec = changelist.get_filters(request)[0][1] self.assertEqual(force_text(filterspec.title), 'publication decade') choices = list(filterspec.choices(changelist)) self.assertEqual(choices[3]['display'], 'the 2000\'s') self.assertEqual(choices[3]['selected'], True) self.assertEqual(choices[3]['query_string'], '?author__id__exact=%s&publication-decade=the+00s' % self.alfred.pk) filterspec = changelist.get_filters(request)[0][0] self.assertEqual(force_text(filterspec.title), 'Verbose Author') choice = select_by(filterspec.choices(changelist), "display", "alfred") self.assertEqual(choice['selected'], True) self.assertEqual(choice['query_string'], '?author__id__exact=%s&publication-decade=the+00s' % self.alfred.pk) def test_listfilter_without_title(self): """ Any filter must define a title. """ modeladmin = DecadeFilterBookAdminWithoutTitle(Book, site) request = self.request_factory.get('/', {}) six.assertRaisesRegex(self, ImproperlyConfigured, "The list filter 'DecadeListFilterWithoutTitle' does not specify a 'title'.", self.get_changelist, request, Book, modeladmin) def test_simplelistfilter_without_parameter(self): """ Any SimpleListFilter must define a parameter_name. """ modeladmin = DecadeFilterBookAdminWithoutParameter(Book, site) request = self.request_factory.get('/', {}) six.assertRaisesRegex(self, ImproperlyConfigured, "The list filter 'DecadeListFilterWithoutParameter' does not specify a 'parameter_name'.", self.get_changelist, request, Book, modeladmin) def test_simplelistfilter_with_none_returning_lookups(self): """ A SimpleListFilter lookups method can return None but disables the filter completely. """ modeladmin = DecadeFilterBookAdminWithNoneReturningLookups(Book, site) request = self.request_factory.get('/', {}) changelist = self.get_changelist(request, Book, modeladmin) filterspec = changelist.get_filters(request)[0] self.assertEqual(len(filterspec), 0) def test_filter_with_failing_queryset(self): """ Ensure that when a filter's queryset method fails, it fails loudly and the corresponding exception doesn't get swallowed. Refs #17828. """ modeladmin = DecadeFilterBookAdminWithFailingQueryset(Book, site) request = self.request_factory.get('/', {}) self.assertRaises(ZeroDivisionError, self.get_changelist, request, Book, modeladmin) def test_simplelistfilter_with_queryset_based_lookups(self): modeladmin = DecadeFilterBookAdminWithQuerysetBasedLookups(Book, site) request = self.request_factory.get('/', {}) changelist = self.get_changelist(request, Book, modeladmin) filterspec = changelist.get_filters(request)[0][0] self.assertEqual(force_text(filterspec.title), 'publication decade') choices = list(filterspec.choices(changelist)) self.assertEqual(len(choices), 3) self.assertEqual(choices[0]['display'], 'All') self.assertEqual(choices[0]['selected'], True) self.assertEqual(choices[0]['query_string'], '?') self.assertEqual(choices[1]['display'], 'the 1990\'s') self.assertEqual(choices[1]['selected'], False) self.assertEqual(choices[1]['query_string'], '?publication-decade=the+90s') self.assertEqual(choices[2]['display'], 'the 2000\'s') self.assertEqual(choices[2]['selected'], False) self.assertEqual(choices[2]['query_string'], '?publication-decade=the+00s') def test_two_characters_long_field(self): """ Ensure that list_filter works with two-characters long field names. Refs #16080. """ modeladmin = BookAdmin(Book, site) request = self.request_factory.get('/', {'no': '207'}) changelist = self.get_changelist(request, Book, modeladmin) # Make sure the correct queryset is returned queryset = changelist.get_queryset(request) self.assertEqual(list(queryset), [self.bio_book]) filterspec = changelist.get_filters(request)[0][-1] self.assertEqual(force_text(filterspec.title), 'number') choices = list(filterspec.choices(changelist)) self.assertEqual(choices[2]['selected'], True) self.assertEqual(choices[2]['query_string'], '?no=207') def test_parameter_ends_with__in__or__isnull(self): """ Ensure that a SimpleListFilter's parameter name is not mistaken for a model field if it ends with '__isnull' or '__in'. Refs #17091. """ # When it ends with '__in' ----------------------------------------- modeladmin = DecadeFilterBookAdminParameterEndsWith__In(Book, site) request = self.request_factory.get('/', {'decade__in': 'the 90s'}) changelist = self.get_changelist(request, Book, modeladmin) # Make sure the correct queryset is returned queryset = changelist.get_queryset(request) self.assertEqual(list(queryset), [self.bio_book]) # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][0] self.assertEqual(force_text(filterspec.title), 'publication decade') choices = list(filterspec.choices(changelist)) self.assertEqual(choices[2]['display'], 'the 1990\'s') self.assertEqual(choices[2]['selected'], True) self.assertEqual(choices[2]['query_string'], '?decade__in=the+90s') # When it ends with '__isnull' --------------------------------------- modeladmin = DecadeFilterBookAdminParameterEndsWith__Isnull(Book, site) request = self.request_factory.get('/', {'decade__isnull': 'the 90s'}) changelist = self.get_changelist(request, Book, modeladmin) # Make sure the correct queryset is returned queryset = changelist.get_queryset(request) self.assertEqual(list(queryset), [self.bio_book]) # Make sure the correct choice is selected filterspec = changelist.get_filters(request)[0][0] self.assertEqual(force_text(filterspec.title), 'publication decade') choices = list(filterspec.choices(changelist)) self.assertEqual(choices[2]['display'], 'the 1990\'s') self.assertEqual(choices[2]['selected'], True) self.assertEqual(choices[2]['query_string'], '?decade__isnull=the+90s') def test_lookup_with_non_string_value(self): """ Ensure choices are set the selected class when using non-string values for lookups in SimpleListFilters. Refs #19318 """ modeladmin = DepartmentFilterEmployeeAdmin(Employee, site) request = self.request_factory.get('/', {'department': self.john.pk}) changelist = self.get_changelist(request, Employee, modeladmin) queryset = changelist.get_queryset(request) self.assertEqual(list(queryset), [self.john]) filterspec = changelist.get_filters(request)[0][-1] self.assertEqual(force_text(filterspec.title), 'department') choices = list(filterspec.choices(changelist)) self.assertEqual(choices[1]['display'], 'DEV') self.assertEqual(choices[1]['selected'], True) self.assertEqual(choices[1]['query_string'], '?department=%s' % self.john.pk) def test_fk_with_to_field(self): """ Ensure that a filter on a FK respects the FK's to_field attribute. Refs #17972. """ modeladmin = EmployeeAdmin(Employee, site) request = self.request_factory.get('/', {}) changelist = self.get_changelist(request, Employee, modeladmin) # Make sure the correct queryset is returned queryset = changelist.get_queryset(request) self.assertEqual(list(queryset), [self.jack, self.john]) filterspec = changelist.get_filters(request)[0][-1] self.assertEqual(force_text(filterspec.title), 'department') choices = list(filterspec.choices(changelist)) self.assertEqual(choices[0]['display'], 'All') self.assertEqual(choices[0]['selected'], True) self.assertEqual(choices[0]['query_string'], '?') self.assertEqual(choices[1]['display'], 'Development') self.assertEqual(choices[1]['selected'], False) self.assertEqual(choices[1]['query_string'], '?department__code__exact=DEV') self.assertEqual(choices[2]['display'], 'Design') self.assertEqual(choices[2]['selected'], False) self.assertEqual(choices[2]['query_string'], '?department__code__exact=DSN') # Filter by Department=='Development' -------------------------------- request = self.request_factory.get('/', {'department__code__exact': 'DEV'}) changelist = self.get_changelist(request, Employee, modeladmin) # Make sure the correct queryset is returned queryset = changelist.get_queryset(request) self.assertEqual(list(queryset), [self.john]) filterspec = changelist.get_filters(request)[0][-1] self.assertEqual(force_text(filterspec.title), 'department') choices = list(filterspec.choices(changelist)) self.assertEqual(choices[0]['display'], 'All') self.assertEqual(choices[0]['selected'], False) self.assertEqual(choices[0]['query_string'], '?') self.assertEqual(choices[1]['display'], 'Development') self.assertEqual(choices[1]['selected'], True) self.assertEqual(choices[1]['query_string'], '?department__code__exact=DEV') self.assertEqual(choices[2]['display'], 'Design') self.assertEqual(choices[2]['selected'], False) self.assertEqual(choices[2]['query_string'], '?department__code__exact=DSN') Django-1.6.11/tests/admin_filters/models.py0000664000175000017500000000251712502407523020234 0ustar timtim00000000000000from __future__ import unicode_literals from django.contrib.auth.models import User from django.db import models from django.utils.encoding import python_2_unicode_compatible @python_2_unicode_compatible class Book(models.Model): title = models.CharField(max_length=50) year = models.PositiveIntegerField(null=True, blank=True) author = models.ForeignKey(User, verbose_name="Verbose Author", related_name='books_authored', blank=True, null=True) contributors = models.ManyToManyField(User, verbose_name="Verbose Contributors", related_name='books_contributed', blank=True, null=True) is_best_seller = models.NullBooleanField(default=0) date_registered = models.DateField(null=True) no = models.IntegerField(verbose_name='number', blank=True, null=True) # This field is intentionally 2 characters long. See #16080. def __str__(self): return self.title @python_2_unicode_compatible class Department(models.Model): code = models.CharField(max_length=4, unique=True) description = models.CharField(max_length=50, blank=True, null=True) def __str__(self): return self.description @python_2_unicode_compatible class Employee(models.Model): department = models.ForeignKey(Department, to_field="code") name = models.CharField(max_length=100) def __str__(self): return self.name Django-1.6.11/tests/createsuperuser/0000775000175000017500000000000012502407547017001 5ustar timtim00000000000000Django-1.6.11/tests/createsuperuser/__init__.py0000664000175000017500000000000012477341424021102 0ustar timtim00000000000000Django-1.6.11/tests/createsuperuser/tests.py0000664000175000017500000000370012502407523020507 0ustar timtim00000000000000from django.contrib.auth import models from django.contrib.auth.management.commands import changepassword from django.core.management import call_command from django.test import TestCase from django.utils.six import StringIO class MultiDBChangepasswordManagementCommandTestCase(TestCase): multi_db = True def setUp(self): self.user = models.User.objects.db_manager('other').create_user(username='joe', password='qwerty') self.stdout = StringIO() def tearDown(self): self.stdout.close() def test_that_changepassword_command_with_database_option_uses_given_db(self): """ Executing the changepassword management command with a database option should operate on the specified DB """ self.assertTrue(self.user.check_password('qwerty')) command = changepassword.Command() command._get_pass = lambda *args: 'not qwerty' command.execute("joe", database='other', stdout=self.stdout) command_output = self.stdout.getvalue().strip() self.assertEqual(command_output, "Changing password for user 'joe'\nPassword changed successfully for user 'joe'") self.assertTrue(models.User.objects.using('other').get(username="joe").check_password("not qwerty")) class MultiDBCreatesuperuserTestCase(TestCase): multi_db = True def test_createsuperuser_command_with_database_option(self): " createsuperuser command should operate on specified DB" new_io = StringIO() call_command("createsuperuser", interactive=False, username="joe", email="joe@somewhere.org", database='other', stdout=new_io ) command_output = new_io.getvalue().strip() self.assertEqual(command_output, 'Superuser created successfully.') u = models.User.objects.using('other').get(username="joe") self.assertEqual(u.email, 'joe@somewhere.org') new_io.close() Django-1.6.11/tests/createsuperuser/models.py0000664000175000017500000000000012502407523020616 0ustar timtim00000000000000Django-1.6.11/tests/m2o_recursive/0000775000175000017500000000000012502407547016344 5ustar timtim00000000000000Django-1.6.11/tests/m2o_recursive/__init__.py0000664000175000017500000000000012477341424020445 0ustar timtim00000000000000Django-1.6.11/tests/m2o_recursive/tests.py0000664000175000017500000000327212502407523020056 0ustar timtim00000000000000from __future__ import absolute_import from django.test import TestCase from .models import Category, Person class ManyToOneRecursiveTests(TestCase): def setUp(self): self.r = Category(id=None, name='Root category', parent=None) self.r.save() self.c = Category(id=None, name='Child category', parent=self.r) self.c.save() def test_m2o_recursive(self): self.assertQuerysetEqual(self.r.child_set.all(), ['']) self.assertEqual(self.r.child_set.get(name__startswith='Child').id, self.c.id) self.assertEqual(self.r.parent, None) self.assertQuerysetEqual(self.c.child_set.all(), []) self.assertEqual(self.c.parent.id, self.r.id) class MultipleManyToOneRecursiveTests(TestCase): def setUp(self): self.dad = Person(full_name='John Smith Senior', mother=None, father=None) self.dad.save() self.mom = Person(full_name='Jane Smith', mother=None, father=None) self.mom.save() self.kid = Person(full_name='John Smith Junior', mother=self.mom, father=self.dad) self.kid.save() def test_m2o_recursive2(self): self.assertEqual(self.kid.mother.id, self.mom.id) self.assertEqual(self.kid.father.id, self.dad.id) self.assertQuerysetEqual(self.dad.fathers_child_set.all(), ['']) self.assertQuerysetEqual(self.mom.mothers_child_set.all(), ['']) self.assertQuerysetEqual(self.kid.mothers_child_set.all(), []) self.assertQuerysetEqual(self.kid.fathers_child_set.all(), []) Django-1.6.11/tests/m2o_recursive/models.py0000664000175000017500000000174212502407523020177 0ustar timtim00000000000000""" 11. Relating an object to itself, many-to-one To define a many-to-one relationship between a model and itself, use ``ForeignKey('self')``. In this example, a ``Category`` is related to itself. That is, each ``Category`` has a parent ``Category``. Set ``related_name`` to designate what the reverse relationship is called. """ from django.db import models from django.utils.encoding import python_2_unicode_compatible @python_2_unicode_compatible class Category(models.Model): name = models.CharField(max_length=20) parent = models.ForeignKey('self', blank=True, null=True, related_name='child_set') def __str__(self): return self.name @python_2_unicode_compatible class Person(models.Model): full_name = models.CharField(max_length=20) mother = models.ForeignKey('self', null=True, related_name='mothers_child_set') father = models.ForeignKey('self', null=True, related_name='fathers_child_set') def __str__(self): return self.full_name Django-1.6.11/tests/test_runner_deprecation_app/0000775000175000017500000000000012502407547021345 5ustar timtim00000000000000Django-1.6.11/tests/test_runner_deprecation_app/__init__.py0000664000175000017500000000000012477341424023446 0ustar timtim00000000000000Django-1.6.11/tests/test_runner_deprecation_app/tests.py0000664000175000017500000000036612502407523023060 0ustar timtim00000000000000import warnings from django.test import TestCase warnings.warn("module-level warning from deprecation_app", DeprecationWarning) class DummyTest(TestCase): def test_warn(self): warnings.warn("warning from test", DeprecationWarning) Django-1.6.11/tests/test_runner_deprecation_app/models.py0000664000175000017500000000007112502407523023172 0ustar timtim00000000000000from django.db import models # Create your models here. Django-1.6.11/tests/transactions_regress/0000775000175000017500000000000012502407547020022 5ustar timtim00000000000000Django-1.6.11/tests/transactions_regress/__init__.py0000664000175000017500000000000012502406330022106 0ustar timtim00000000000000Django-1.6.11/tests/transactions_regress/tests.py0000664000175000017500000003606012502407523021535 0ustar timtim00000000000000from __future__ import absolute_import from django.db import (connection, connections, transaction, DEFAULT_DB_ALIAS, DatabaseError, IntegrityError) from django.db.transaction import commit_on_success, commit_manually, TransactionManagementError from django.test import TransactionTestCase, skipUnlessDBFeature from django.test.utils import override_settings, IgnorePendingDeprecationWarningsMixin from django.utils.unittest import skipIf, skipUnless, SkipTest from .models import Mod, M2mA, M2mB, SubMod class ModelInheritanceTests(TransactionTestCase): available_apps = ['transactions_regress'] def test_save(self): # First, create a SubMod, then try to save another with conflicting # cnt field. The problem was that transactions were committed after # every parent save when not in managed transaction. As the cnt # conflict is in the second model, we can check if the first save # was committed or not. SubMod(fld=1, cnt=1).save() # We should have committed the transaction for the above - assert this. connection.rollback() self.assertEqual(SubMod.objects.count(), 1) try: SubMod(fld=2, cnt=1).save() except IntegrityError: connection.rollback() self.assertEqual(SubMod.objects.count(), 1) self.assertEqual(Mod.objects.count(), 1) class TestTransactionClosing(IgnorePendingDeprecationWarningsMixin, TransactionTestCase): """ Tests to make sure that transactions are properly closed when they should be, and aren't left pending after operations have been performed in them. Refs #9964. """ available_apps = [ 'transactions_regress', 'django.contrib.auth', 'django.contrib.contenttypes', ] def test_raw_committed_on_success(self): """ Make sure a transaction consisting of raw SQL execution gets committed by the commit_on_success decorator. """ @commit_on_success def raw_sql(): "Write a record using raw sql under a commit_on_success decorator" cursor = connection.cursor() cursor.execute("INSERT into transactions_regress_mod (fld) values (18)") raw_sql() # Rollback so that if the decorator didn't commit, the record is unwritten transaction.rollback() self.assertEqual(Mod.objects.count(), 1) # Check that the record is in the DB obj = Mod.objects.all()[0] self.assertEqual(obj.fld, 18) def test_commit_manually_enforced(self): """ Make sure that under commit_manually, even "read-only" transaction require closure (commit or rollback), and a transaction left pending is treated as an error. """ @commit_manually def non_comitter(): "Execute a managed transaction with read-only operations and fail to commit" Mod.objects.count() self.assertRaises(TransactionManagementError, non_comitter) def test_commit_manually_commit_ok(self): """ Test that under commit_manually, a committed transaction is accepted by the transaction management mechanisms """ @commit_manually def committer(): """ Perform a database query, then commit the transaction """ Mod.objects.count() transaction.commit() try: committer() except TransactionManagementError: self.fail("Commit did not clear the transaction state") def test_commit_manually_rollback_ok(self): """ Test that under commit_manually, a rolled-back transaction is accepted by the transaction management mechanisms """ @commit_manually def roller_back(): """ Perform a database query, then rollback the transaction """ Mod.objects.count() transaction.rollback() try: roller_back() except TransactionManagementError: self.fail("Rollback did not clear the transaction state") def test_commit_manually_enforced_after_commit(self): """ Test that under commit_manually, if a transaction is committed and an operation is performed later, we still require the new transaction to be closed """ @commit_manually def fake_committer(): "Query, commit, then query again, leaving with a pending transaction" Mod.objects.count() transaction.commit() Mod.objects.count() self.assertRaises(TransactionManagementError, fake_committer) @skipUnlessDBFeature('supports_transactions') def test_reuse_cursor_reference(self): """ Make sure transaction closure is enforced even when the queries are performed through a single cursor reference retrieved in the beginning (this is to show why it is wrong to set the transaction dirty only when a cursor is fetched from the connection). """ @commit_on_success def reuse_cursor_ref(): """ Fetch a cursor, perform an query, rollback to close the transaction, then write a record (in a new transaction) using the same cursor object (reference). All this under commit_on_success, so the second insert should be committed. """ cursor = connection.cursor() cursor.execute("INSERT into transactions_regress_mod (fld) values (2)") transaction.rollback() cursor.execute("INSERT into transactions_regress_mod (fld) values (2)") reuse_cursor_ref() # Rollback so that if the decorator didn't commit, the record is unwritten transaction.rollback() self.assertEqual(Mod.objects.count(), 1) obj = Mod.objects.all()[0] self.assertEqual(obj.fld, 2) def test_failing_query_transaction_closed(self): """ Make sure that under commit_on_success, a transaction is rolled back even if the first database-modifying operation fails. This is prompted by http://code.djangoproject.com/ticket/6669 (and based on sample code posted there to exemplify the problem): Before Django 1.3, transactions were only marked "dirty" by the save() function after it successfully wrote the object to the database. """ from django.contrib.auth.models import User @transaction.commit_on_success def create_system_user(): "Create a user in a transaction" user = User.objects.create_user(username='system', password='iamr00t', email='root@SITENAME.com') # Redundant, just makes sure the user id was read back from DB Mod.objects.create(fld=user.pk) # Create a user create_system_user() with self.assertRaises(DatabaseError): # The second call to create_system_user should fail for violating # a unique constraint (it's trying to re-create the same user) create_system_user() # Try to read the database. If the last transaction was indeed closed, # this should cause no problems User.objects.all()[0] @override_settings(DEBUG=True) def test_failing_query_transaction_closed_debug(self): """ Regression for #6669. Same test as above, with DEBUG=True. """ self.test_failing_query_transaction_closed() @skipIf(connection.vendor == 'sqlite' and connection.settings_dict['TEST_NAME'] in (None, '', ':memory:'), "Cannot establish two connections to an in-memory SQLite database.") class TestNewConnection(IgnorePendingDeprecationWarningsMixin, TransactionTestCase): """ Check that new connections don't have special behaviour. """ available_apps = ['transactions_regress'] def setUp(self): self._old_backend = connections[DEFAULT_DB_ALIAS] settings = self._old_backend.settings_dict.copy() new_backend = self._old_backend.__class__(settings, DEFAULT_DB_ALIAS) connections[DEFAULT_DB_ALIAS] = new_backend def tearDown(self): try: connections[DEFAULT_DB_ALIAS].abort() connections[DEFAULT_DB_ALIAS].close() finally: connections[DEFAULT_DB_ALIAS] = self._old_backend def test_commit(self): """ Users are allowed to commit and rollback connections. """ connection.set_autocommit(False) try: # The starting value is False, not None. self.assertIs(connection._dirty, False) list(Mod.objects.all()) self.assertTrue(connection.is_dirty()) connection.commit() self.assertFalse(connection.is_dirty()) list(Mod.objects.all()) self.assertTrue(connection.is_dirty()) connection.rollback() self.assertFalse(connection.is_dirty()) finally: connection.set_autocommit(True) def test_enter_exit_management(self): orig_dirty = connection._dirty connection.enter_transaction_management() connection.leave_transaction_management() self.assertEqual(orig_dirty, connection._dirty) @skipUnless(connection.vendor == 'postgresql', "This test only valid for PostgreSQL") class TestPostgresAutocommitAndIsolation(IgnorePendingDeprecationWarningsMixin, TransactionTestCase): """ Tests to make sure psycopg2's autocommit mode and isolation level is restored after entering and leaving transaction management. Refs #16047, #18130. """ available_apps = ['transactions_regress'] def setUp(self): from psycopg2.extensions import (ISOLATION_LEVEL_AUTOCOMMIT, ISOLATION_LEVEL_SERIALIZABLE, TRANSACTION_STATUS_IDLE) self._autocommit = ISOLATION_LEVEL_AUTOCOMMIT self._serializable = ISOLATION_LEVEL_SERIALIZABLE self._idle = TRANSACTION_STATUS_IDLE # We want a clean backend with autocommit = True, so # first we need to do a bit of work to have that. self._old_backend = connections[DEFAULT_DB_ALIAS] settings = self._old_backend.settings_dict.copy() opts = settings['OPTIONS'].copy() opts['isolation_level'] = ISOLATION_LEVEL_SERIALIZABLE settings['OPTIONS'] = opts new_backend = self._old_backend.__class__(settings, DEFAULT_DB_ALIAS) connections[DEFAULT_DB_ALIAS] = new_backend def tearDown(self): try: connections[DEFAULT_DB_ALIAS].abort() finally: connections[DEFAULT_DB_ALIAS].close() connections[DEFAULT_DB_ALIAS] = self._old_backend def test_initial_autocommit_state(self): # Autocommit is activated when the connection is created. connection.cursor().close() self.assertTrue(connection.autocommit) def test_transaction_management(self): transaction.enter_transaction_management() self.assertFalse(connection.autocommit) self.assertEqual(connection.isolation_level, self._serializable) transaction.leave_transaction_management() self.assertTrue(connection.autocommit) def test_transaction_stacking(self): transaction.enter_transaction_management() self.assertFalse(connection.autocommit) self.assertEqual(connection.isolation_level, self._serializable) transaction.enter_transaction_management() self.assertFalse(connection.autocommit) self.assertEqual(connection.isolation_level, self._serializable) transaction.leave_transaction_management() self.assertFalse(connection.autocommit) self.assertEqual(connection.isolation_level, self._serializable) transaction.leave_transaction_management() self.assertTrue(connection.autocommit) def test_enter_autocommit(self): transaction.enter_transaction_management() self.assertFalse(connection.autocommit) self.assertEqual(connection.isolation_level, self._serializable) list(Mod.objects.all()) self.assertTrue(transaction.is_dirty()) # Enter autocommit mode again. transaction.enter_transaction_management(False) self.assertFalse(transaction.is_dirty()) self.assertEqual( connection.connection.get_transaction_status(), self._idle) list(Mod.objects.all()) self.assertFalse(transaction.is_dirty()) transaction.leave_transaction_management() self.assertFalse(connection.autocommit) self.assertEqual(connection.isolation_level, self._serializable) transaction.leave_transaction_management() self.assertTrue(connection.autocommit) class TestManyToManyAddTransaction(IgnorePendingDeprecationWarningsMixin, TransactionTestCase): available_apps = ['transactions_regress'] def test_manyrelated_add_commit(self): "Test for https://code.djangoproject.com/ticket/16818" a = M2mA.objects.create() b = M2mB.objects.create(fld=10) a.others.add(b) # We're in a TransactionTestCase and have not changed transaction # behavior from default of "autocommit", so this rollback should not # actually do anything. If it does in fact undo our add, that's a bug # that the bulk insert was not auto-committed. transaction.rollback() self.assertEqual(a.others.count(), 1) class SavepointTest(IgnorePendingDeprecationWarningsMixin, TransactionTestCase): available_apps = ['transactions_regress'] @skipIf(connection.vendor == 'sqlite', "SQLite doesn't support savepoints in managed mode") @skipUnlessDBFeature('uses_savepoints') def test_savepoint_commit(self): @commit_manually def work(): mod = Mod.objects.create(fld=1) pk = mod.pk sid = transaction.savepoint() Mod.objects.filter(pk=pk).update(fld=10) transaction.savepoint_commit(sid) mod2 = Mod.objects.get(pk=pk) transaction.commit() self.assertEqual(mod2.fld, 10) work() @skipIf(connection.vendor == 'sqlite', "SQLite doesn't support savepoints in managed mode") @skipUnlessDBFeature('uses_savepoints') def test_savepoint_rollback(self): # _mysql_storage_engine issues a query and as such can't be applied in # a skipIf decorator since that would execute the query on module load. if (connection.vendor == 'mysql' and connection.features._mysql_storage_engine == 'MyISAM'): raise SkipTest("MyISAM MySQL storage engine doesn't support savepoints") @commit_manually def work(): mod = Mod.objects.create(fld=1) pk = mod.pk sid = transaction.savepoint() Mod.objects.filter(pk=pk).update(fld=20) transaction.savepoint_rollback(sid) mod2 = Mod.objects.get(pk=pk) transaction.commit() self.assertEqual(mod2.fld, 1) work() Django-1.6.11/tests/transactions_regress/models.py0000664000175000017500000000043212502407523021650 0ustar timtim00000000000000from django.db import models class Mod(models.Model): fld = models.IntegerField() class SubMod(Mod): cnt = models.IntegerField(unique=True) class M2mA(models.Model): others = models.ManyToManyField('M2mB') class M2mB(models.Model): fld = models.IntegerField() Django-1.6.11/tests/expressions_regress/0000775000175000017500000000000012502407547017674 5ustar timtim00000000000000Django-1.6.11/tests/expressions_regress/__init__.py0000664000175000017500000000000012502406330021760 0ustar timtim00000000000000Django-1.6.11/tests/expressions_regress/tests.py0000664000175000017500000004010112502407523021376 0ustar timtim00000000000000""" Spanning tests for all the operations that F() expressions can perform. """ from __future__ import absolute_import import datetime from django.db import connection from django.db.models import F from django.test import TestCase, Approximate, skipUnlessDBFeature from .models import Number, Experiment class ExpressionsRegressTests(TestCase): def setUp(self): Number(integer=-1).save() Number(integer=42).save() Number(integer=1337).save() self.assertEqual(Number.objects.update(float=F('integer')), 3) def test_fill_with_value_from_same_object(self): """ We can fill a value in all objects with an other value of the same object. """ self.assertQuerysetEqual( Number.objects.all(), [ '', '', '' ], ordered=False ) def test_increment_value(self): """ We can increment a value of all objects in a query set. """ self.assertEqual( Number.objects.filter(integer__gt=0) .update(integer=F('integer') + 1), 2) self.assertQuerysetEqual( Number.objects.all(), [ '', '', '' ], ordered=False ) def test_filter_not_equals_other_field(self): """ We can filter for objects, where a value is not equals the value of an other field. """ self.assertEqual( Number.objects.filter(integer__gt=0) .update(integer=F('integer') + 1), 2) self.assertQuerysetEqual( Number.objects.exclude(float=F('integer')), [ '', '' ], ordered=False ) def test_complex_expressions(self): """ Complex expressions of different connection types are possible. """ n = Number.objects.create(integer=10, float=123.45) self.assertEqual(Number.objects.filter(pk=n.pk) .update(float=F('integer') + F('float') * 2), 1) self.assertEqual(Number.objects.get(pk=n.pk).integer, 10) self.assertEqual(Number.objects.get(pk=n.pk).float, Approximate(256.900, places=3)) class ExpressionOperatorTests(TestCase): def setUp(self): self.n = Number.objects.create(integer=42, float=15.5) def test_lefthand_addition(self): # LH Addition of floats and integers Number.objects.filter(pk=self.n.pk).update( integer=F('integer') + 15, float=F('float') + 42.7 ) self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 57) self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(58.200, places=3)) def test_lefthand_subtraction(self): # LH Subtraction of floats and integers Number.objects.filter(pk=self.n.pk).update(integer=F('integer') - 15, float=F('float') - 42.7) self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 27) self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(-27.200, places=3)) def test_lefthand_multiplication(self): # Multiplication of floats and integers Number.objects.filter(pk=self.n.pk).update(integer=F('integer') * 15, float=F('float') * 42.7) self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 630) self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(661.850, places=3)) def test_lefthand_division(self): # LH Division of floats and integers Number.objects.filter(pk=self.n.pk).update(integer=F('integer') / 2, float=F('float') / 42.7) self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 21) self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(0.363, places=3)) def test_lefthand_modulo(self): # LH Modulo arithmetic on integers Number.objects.filter(pk=self.n.pk).update(integer=F('integer') % 20) self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 2) self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3)) def test_lefthand_bitwise_and(self): # LH Bitwise ands on integers Number.objects.filter(pk=self.n.pk).update(integer=F('integer').bitand(56)) self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 40) self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3)) @skipUnlessDBFeature('supports_bitwise_or') def test_lefthand_bitwise_or(self): # LH Bitwise or on integers Number.objects.filter(pk=self.n.pk).update(integer=F('integer').bitor(48)) self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 58) self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3)) def test_right_hand_addition(self): # Right hand operators Number.objects.filter(pk=self.n.pk).update(integer=15 + F('integer'), float=42.7 + F('float')) # RH Addition of floats and integers self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 57) self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(58.200, places=3)) def test_right_hand_subtraction(self): Number.objects.filter(pk=self.n.pk).update(integer=15 - F('integer'), float=42.7 - F('float')) # RH Subtraction of floats and integers self.assertEqual(Number.objects.get(pk=self.n.pk).integer, -27) self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(27.200, places=3)) def test_right_hand_multiplication(self): # RH Multiplication of floats and integers Number.objects.filter(pk=self.n.pk).update(integer=15 * F('integer'), float=42.7 * F('float')) self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 630) self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(661.850, places=3)) def test_right_hand_division(self): # RH Division of floats and integers Number.objects.filter(pk=self.n.pk).update(integer=640 / F('integer'), float=42.7 / F('float')) self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 15) self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(2.755, places=3)) def test_right_hand_modulo(self): # RH Modulo arithmetic on integers Number.objects.filter(pk=self.n.pk).update(integer=69 % F('integer')) self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 27) self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3)) class FTimeDeltaTests(TestCase): def setUp(self): sday = datetime.date(2010, 6, 25) stime = datetime.datetime(2010, 6, 25, 12, 15, 30, 747000) midnight = datetime.time(0) delta0 = datetime.timedelta(0) delta1 = datetime.timedelta(microseconds=253000) delta2 = datetime.timedelta(seconds=44) delta3 = datetime.timedelta(hours=21, minutes=8) delta4 = datetime.timedelta(days=10) # Test data is set so that deltas and delays will be # strictly increasing. self.deltas = [] self.delays = [] self.days_long = [] # e0: started same day as assigned, zero duration end = stime+delta0 e0 = Experiment.objects.create(name='e0', assigned=sday, start=stime, end=end, completed=end.date()) self.deltas.append(delta0) self.delays.append(e0.start- datetime.datetime.combine(e0.assigned, midnight)) self.days_long.append(e0.completed-e0.assigned) # e1: started one day after assigned, tiny duration, data # set so that end time has no fractional seconds, which # tests an edge case on sqlite. This Experiment is only # included in the test data when the DB supports microsecond # precision. if connection.features.supports_microsecond_precision: delay = datetime.timedelta(1) end = stime + delay + delta1 e1 = Experiment.objects.create(name='e1', assigned=sday, start=stime+delay, end=end, completed=end.date()) self.deltas.append(delta1) self.delays.append(e1.start- datetime.datetime.combine(e1.assigned, midnight)) self.days_long.append(e1.completed-e1.assigned) # e2: started three days after assigned, small duration end = stime+delta2 e2 = Experiment.objects.create(name='e2', assigned=sday-datetime.timedelta(3), start=stime, end=end, completed=end.date()) self.deltas.append(delta2) self.delays.append(e2.start- datetime.datetime.combine(e2.assigned, midnight)) self.days_long.append(e2.completed-e2.assigned) # e3: started four days after assigned, medium duration delay = datetime.timedelta(4) end = stime + delay + delta3 e3 = Experiment.objects.create(name='e3', assigned=sday, start=stime+delay, end=end, completed=end.date()) self.deltas.append(delta3) self.delays.append(e3.start- datetime.datetime.combine(e3.assigned, midnight)) self.days_long.append(e3.completed-e3.assigned) # e4: started 10 days after assignment, long duration end = stime + delta4 e4 = Experiment.objects.create(name='e4', assigned=sday-datetime.timedelta(10), start=stime, end=end, completed=end.date()) self.deltas.append(delta4) self.delays.append(e4.start- datetime.datetime.combine(e4.assigned, midnight)) self.days_long.append(e4.completed-e4.assigned) self.expnames = [e.name for e in Experiment.objects.all()] def test_multiple_query_compilation(self): # Ticket #21643 queryset = Experiment.objects.filter(end__lt=F('start') + datetime.timedelta(hours=1)) q1 = str(queryset.query) q2 = str(queryset.query) self.assertEqual(q1, q2) def test_query_clone(self): # Ticket #21643 qs = Experiment.objects.filter(end__lt=F('start') + datetime.timedelta(hours=1)) qs2 = qs.all() list(qs) list(qs2) def test_delta_add(self): for i in range(len(self.deltas)): delta = self.deltas[i] test_set = [e.name for e in Experiment.objects.filter(end__lt=F('start')+delta)] self.assertEqual(test_set, self.expnames[:i]) test_set = [e.name for e in Experiment.objects.filter(end__lte=F('start')+delta)] self.assertEqual(test_set, self.expnames[:i+1]) def test_delta_subtract(self): for i in range(len(self.deltas)): delta = self.deltas[i] test_set = [e.name for e in Experiment.objects.filter(start__gt=F('end')-delta)] self.assertEqual(test_set, self.expnames[:i]) test_set = [e.name for e in Experiment.objects.filter(start__gte=F('end')-delta)] self.assertEqual(test_set, self.expnames[:i+1]) def test_exclude(self): for i in range(len(self.deltas)): delta = self.deltas[i] test_set = [e.name for e in Experiment.objects.exclude(end__lt=F('start')+delta)] self.assertEqual(test_set, self.expnames[i:]) test_set = [e.name for e in Experiment.objects.exclude(end__lte=F('start')+delta)] self.assertEqual(test_set, self.expnames[i+1:]) def test_date_comparison(self): for i in range(len(self.days_long)): days = self.days_long[i] test_set = [e.name for e in Experiment.objects.filter(completed__lt=F('assigned')+days)] self.assertEqual(test_set, self.expnames[:i]) test_set = [e.name for e in Experiment.objects.filter(completed__lte=F('assigned')+days)] self.assertEqual(test_set, self.expnames[:i+1]) @skipUnlessDBFeature("supports_mixed_date_datetime_comparisons") def test_mixed_comparisons1(self): for i in range(len(self.delays)): delay = self.delays[i] if not connection.features.supports_microsecond_precision: delay = datetime.timedelta(delay.days, delay.seconds) test_set = [e.name for e in Experiment.objects.filter(assigned__gt=F('start')-delay)] self.assertEqual(test_set, self.expnames[:i]) test_set = [e.name for e in Experiment.objects.filter(assigned__gte=F('start')-delay)] self.assertEqual(test_set, self.expnames[:i+1]) def test_mixed_comparisons2(self): delays = [datetime.timedelta(delay.days) for delay in self.delays] for i in range(len(delays)): delay = delays[i] test_set = [e.name for e in Experiment.objects.filter(start__lt=F('assigned')+delay)] self.assertEqual(test_set, self.expnames[:i]) test_set = [e.name for e in Experiment.objects.filter(start__lte=F('assigned')+delay+ datetime.timedelta(1))] self.assertEqual(test_set, self.expnames[:i+1]) def test_delta_update(self): for i in range(len(self.deltas)): delta = self.deltas[i] exps = Experiment.objects.all() expected_durations = [e.duration() for e in exps] expected_starts = [e.start+delta for e in exps] expected_ends = [e.end+delta for e in exps] Experiment.objects.update(start=F('start')+delta, end=F('end')+delta) exps = Experiment.objects.all() new_starts = [e.start for e in exps] new_ends = [e.end for e in exps] new_durations = [e.duration() for e in exps] self.assertEqual(expected_starts, new_starts) self.assertEqual(expected_ends, new_ends) self.assertEqual(expected_durations, new_durations) def test_delta_invalid_op_mult(self): raised = False try: r = repr(Experiment.objects.filter(end__lt=F('start')*self.deltas[0])) except TypeError: raised = True self.assertTrue(raised, "TypeError not raised on attempt to multiply datetime by timedelta.") def test_delta_invalid_op_div(self): raised = False try: r = repr(Experiment.objects.filter(end__lt=F('start')/self.deltas[0])) except TypeError: raised = True self.assertTrue(raised, "TypeError not raised on attempt to divide datetime by timedelta.") def test_delta_invalid_op_mod(self): raised = False try: r = repr(Experiment.objects.filter(end__lt=F('start')%self.deltas[0])) except TypeError: raised = True self.assertTrue(raised, "TypeError not raised on attempt to modulo divide datetime by timedelta.") def test_delta_invalid_op_and(self): raised = False try: r = repr(Experiment.objects.filter(end__lt=F('start').bitand(self.deltas[0]))) except TypeError: raised = True self.assertTrue(raised, "TypeError not raised on attempt to binary and a datetime with a timedelta.") def test_delta_invalid_op_or(self): raised = False try: r = repr(Experiment.objects.filter(end__lt=F('start').bitor(self.deltas[0]))) except TypeError: raised = True self.assertTrue(raised, "TypeError not raised on attempt to binary or a datetime with a timedelta.") Django-1.6.11/tests/expressions_regress/models.py0000664000175000017500000000137412502407523021530 0ustar timtim00000000000000from __future__ import unicode_literals from django.utils.encoding import python_2_unicode_compatible """ Model for testing arithmetic expressions. """ from django.db import models @python_2_unicode_compatible class Number(models.Model): integer = models.IntegerField(db_column='the_integer') float = models.FloatField(null=True, db_column='the_float') def __str__(self): return '%i, %.3f' % (self.integer, self.float) class Experiment(models.Model): name = models.CharField(max_length=24) assigned = models.DateField() completed = models.DateField() start = models.DateTimeField() end = models.DateTimeField() class Meta: ordering = ('name',) def duration(self): return self.end - self.start Django-1.6.11/tests/model_forms/0000775000175000017500000000000012502407547016066 5ustar timtim00000000000000Django-1.6.11/tests/model_forms/test.png0000664000175000017500000000074212477341424017560 0ustar timtim00000000000000PNG  IHDRh6 pHYs  tIME  ' IDATxڕK(Dqƿsw(YXXLl Q"Ăe$k MIʂW ;c.qsC}cC [9,—jLLDgG-K-gs-Xx7GF&I:$)4W,kG%@8-u5򤸄1v fEUזn|wM%@td%gPo,nHp|q{!%7?\-ͬz;{^vέ^ rPj80պtS)pzuaJ|Q^trpy=. EUhoi`m3lh+sȒ~ry}ޯՠxHYIENDB`Django-1.6.11/tests/model_forms/__init__.py0000664000175000017500000000000012477341424020167 0ustar timtim00000000000000Django-1.6.11/tests/model_forms/tests.py0000664000175000017500000022575612502407523017615 0ustar timtim00000000000000from __future__ import absolute_import, unicode_literals import datetime import os from decimal import Decimal import warnings from django import forms from django.core.exceptions import FieldError from django.core.files.uploadedfile import SimpleUploadedFile from django.core.validators import ValidationError from django.db import connection from django.db.models.query import EmptyQuerySet from django.forms.models import model_to_dict from django.utils._os import upath from django.utils.unittest import skipUnless from django.test import TestCase from django.utils import six from .models import (Article, ArticleStatus, BetterWriter, BigInt, Book, Category, CommaSeparatedInteger, CustomFieldForExclusionModel, DerivedBook, DerivedPost, ExplicitPK, FlexibleDatePost, ImprovedArticle, ImprovedArticleWithParentLink, Inventory, Post, Price, Product, TextFile, Writer, WriterProfile, Colour, ColourfulItem, ArticleStatusNote, DateTimePost, CustomErrorMessage, test_images) if test_images: from .models import ImageFile, OptionalImageFile class ImageFileForm(forms.ModelForm): class Meta: model = ImageFile fields = '__all__' class OptionalImageFileForm(forms.ModelForm): class Meta: model = OptionalImageFile fields = '__all__' class ProductForm(forms.ModelForm): class Meta: model = Product fields = '__all__' class PriceForm(forms.ModelForm): class Meta: model = Price fields = '__all__' class BookForm(forms.ModelForm): class Meta: model = Book fields = '__all__' class DerivedBookForm(forms.ModelForm): class Meta: model = DerivedBook fields = '__all__' class ExplicitPKForm(forms.ModelForm): class Meta: model = ExplicitPK fields = ('key', 'desc',) class PostForm(forms.ModelForm): class Meta: model = Post fields = '__all__' class DateTimePostForm(forms.ModelForm): class Meta: model = DateTimePost fields = '__all__' class DerivedPostForm(forms.ModelForm): class Meta: model = DerivedPost fields = '__all__' class CustomWriterForm(forms.ModelForm): name = forms.CharField(required=False) class Meta: model = Writer fields = '__all__' class FlexDatePostForm(forms.ModelForm): class Meta: model = FlexibleDatePost fields = '__all__' class BaseCategoryForm(forms.ModelForm): class Meta: model = Category fields = '__all__' class ArticleForm(forms.ModelForm): class Meta: model = Article fields = '__all__' class PartialArticleForm(forms.ModelForm): class Meta: model = Article fields = ('headline','pub_date') class RoykoForm(forms.ModelForm): class Meta: model = Writer fields = '__all__' class TestArticleForm(forms.ModelForm): class Meta: model = Article fields = '__all__' class PartialArticleFormWithSlug(forms.ModelForm): class Meta: model = Article fields = ('headline', 'slug', 'pub_date') class ArticleStatusForm(forms.ModelForm): class Meta: model = ArticleStatus fields = '__all__' class InventoryForm(forms.ModelForm): class Meta: model = Inventory fields = '__all__' class SelectInventoryForm(forms.Form): items = forms.ModelMultipleChoiceField(Inventory.objects.all(), to_field_name='barcode') class CustomFieldForExclusionForm(forms.ModelForm): class Meta: model = CustomFieldForExclusionModel fields = ['name', 'markup'] class ShortCategory(forms.ModelForm): name = forms.CharField(max_length=5) slug = forms.CharField(max_length=5) url = forms.CharField(max_length=3) class Meta: model = Category fields = '__all__' class ImprovedArticleForm(forms.ModelForm): class Meta: model = ImprovedArticle fields = '__all__' class ImprovedArticleWithParentLinkForm(forms.ModelForm): class Meta: model = ImprovedArticleWithParentLink fields = '__all__' class BetterWriterForm(forms.ModelForm): class Meta: model = BetterWriter fields = '__all__' class WriterProfileForm(forms.ModelForm): class Meta: model = WriterProfile fields = '__all__' class TextFileForm(forms.ModelForm): class Meta: model = TextFile fields = '__all__' class BigIntForm(forms.ModelForm): class Meta: model = BigInt fields = '__all__' class ModelFormWithMedia(forms.ModelForm): class Media: js = ('/some/form/javascript',) css = { 'all': ('/some/form/css',) } class Meta: model = TextFile fields = '__all__' class CommaSeparatedIntegerForm(forms.ModelForm): class Meta: model = CommaSeparatedInteger fields = '__all__' class PriceFormWithoutQuantity(forms.ModelForm): class Meta: model = Price exclude = ('quantity',) class ColourfulItemForm(forms.ModelForm): class Meta: model = ColourfulItem fields = '__all__' # model forms for testing work on #9321: class StatusNoteForm(forms.ModelForm): class Meta: model = ArticleStatusNote fields = '__all__' class StatusNoteCBM2mForm(forms.ModelForm): class Meta: model = ArticleStatusNote fields = '__all__' widgets = {'status': forms.CheckboxSelectMultiple} class CustomErrorMessageForm(forms.ModelForm): name1 = forms.CharField(error_messages={'invalid': 'Form custom error message.'}) class Meta: fields = '__all__' model = CustomErrorMessage class ModelFormBaseTest(TestCase): def test_base_form(self): self.assertEqual(list(BaseCategoryForm.base_fields), ['name', 'slug', 'url']) def test_missing_fields_attribute(self): with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always", PendingDeprecationWarning) class MissingFieldsForm(forms.ModelForm): class Meta: model = Category # There is some internal state in warnings module which means that # if a warning has been seen already, the catch_warnings won't # have recorded it. The following line therefore will not work reliably: # self.assertEqual(w[0].category, PendingDeprecationWarning) # Until end of the deprecation cycle, should still create the # form as before: self.assertEqual(list(MissingFieldsForm.base_fields), ['name', 'slug', 'url']) def test_extra_fields(self): class ExtraFields(BaseCategoryForm): some_extra_field = forms.BooleanField() self.assertEqual(list(ExtraFields.base_fields), ['name', 'slug', 'url', 'some_extra_field']) def test_replace_field(self): class ReplaceField(forms.ModelForm): url = forms.BooleanField() class Meta: model = Category fields = '__all__' self.assertIsInstance(ReplaceField.base_fields['url'], forms.fields.BooleanField) def test_replace_field_variant_2(self): # Should have the same result as before, # but 'fields' attribute specified differently class ReplaceField(forms.ModelForm): url = forms.BooleanField() class Meta: model = Category fields = ['url'] self.assertIsInstance(ReplaceField.base_fields['url'], forms.fields.BooleanField) def test_replace_field_variant_3(self): # Should have the same result as before, # but 'fields' attribute specified differently class ReplaceField(forms.ModelForm): url = forms.BooleanField() class Meta: model = Category fields = [] # url will still appear, since it is explicit above self.assertIsInstance(ReplaceField.base_fields['url'], forms.fields.BooleanField) def test_override_field(self): class WriterForm(forms.ModelForm): book = forms.CharField(required=False) class Meta: model = Writer fields = '__all__' wf = WriterForm({'name': 'Richard Lockridge'}) self.assertTrue(wf.is_valid()) def test_limit_nonexistent_field(self): expected_msg = 'Unknown field(s) (nonexistent) specified for Category' with self.assertRaisesMessage(FieldError, expected_msg): class InvalidCategoryForm(forms.ModelForm): class Meta: model = Category fields = ['nonexistent'] def test_limit_fields_with_string(self): expected_msg = "CategoryForm.Meta.fields cannot be a string. Did you mean to type: ('url',)?" with self.assertRaisesMessage(TypeError, expected_msg): class CategoryForm(forms.ModelForm): class Meta: model = Category fields = ('url') # note the missing comma def test_exclude_fields(self): class ExcludeFields(forms.ModelForm): class Meta: model = Category exclude = ['url'] self.assertEqual(list(ExcludeFields.base_fields), ['name', 'slug']) def test_exclude_nonexistent_field(self): class ExcludeFields(forms.ModelForm): class Meta: model = Category exclude = ['nonexistent'] self.assertEqual(list(ExcludeFields.base_fields), ['name', 'slug', 'url']) def test_exclude_fields_with_string(self): expected_msg = "CategoryForm.Meta.exclude cannot be a string. Did you mean to type: ('url',)?" with self.assertRaisesMessage(TypeError, expected_msg): class CategoryForm(forms.ModelForm): class Meta: model = Category exclude = ('url') # note the missing comma def test_confused_form(self): class ConfusedForm(forms.ModelForm): """ Using 'fields' *and* 'exclude'. Not sure why you'd want to do this, but uh, "be liberal in what you accept" and all. """ class Meta: model = Category fields = ['name', 'url'] exclude = ['url'] self.assertEqual(list(ConfusedForm.base_fields), ['name']) def test_mixmodel_form(self): class MixModelForm(BaseCategoryForm): """ Don't allow more than one 'model' definition in the inheritance hierarchy. Technically, it would generate a valid form, but the fact that the resulting save method won't deal with multiple objects is likely to trip up people not familiar with the mechanics. """ class Meta: model = Article fields = '__all__' # MixModelForm is now an Article-related thing, because MixModelForm.Meta # overrides BaseCategoryForm.Meta. self.assertEqual( list(MixModelForm.base_fields), ['headline', 'slug', 'pub_date', 'writer', 'article', 'categories', 'status'] ) def test_article_form(self): self.assertEqual( list(ArticleForm.base_fields), ['headline', 'slug', 'pub_date', 'writer', 'article', 'categories', 'status'] ) def test_bad_form(self): #First class with a Meta class wins... class BadForm(ArticleForm, BaseCategoryForm): pass self.assertEqual( list(BadForm.base_fields), ['headline', 'slug', 'pub_date', 'writer', 'article', 'categories', 'status'] ) def test_invalid_meta_model(self): class InvalidModelForm(forms.ModelForm): class Meta: pass # no model # Can't create new form with self.assertRaises(ValueError): f = InvalidModelForm() # Even if you provide a model instance with self.assertRaises(ValueError): f = InvalidModelForm(instance=Category) def test_subcategory_form(self): class SubCategoryForm(BaseCategoryForm): """ Subclassing without specifying a Meta on the class will use the parent's Meta (or the first parent in the MRO if there are multiple parent classes). """ pass self.assertEqual(list(SubCategoryForm.base_fields), ['name', 'slug', 'url']) def test_subclassmeta_form(self): class SomeCategoryForm(forms.ModelForm): checkbox = forms.BooleanField() class Meta: model = Category fields = '__all__' class SubclassMeta(SomeCategoryForm): """ We can also subclass the Meta inner class to change the fields list. """ class Meta(SomeCategoryForm.Meta): exclude = ['url'] self.assertHTMLEqual( str(SubclassMeta()), """ """ ) def test_orderfields_form(self): class OrderFields(forms.ModelForm): class Meta: model = Category fields = ['url', 'name'] self.assertEqual(list(OrderFields.base_fields), ['url', 'name']) self.assertHTMLEqual( str(OrderFields()), """ """ ) def test_orderfields2_form(self): class OrderFields2(forms.ModelForm): class Meta: model = Category fields = ['slug', 'url', 'name'] exclude = ['url'] self.assertEqual(list(OrderFields2.base_fields), ['slug', 'name']) class FieldOverridesTroughFormMetaForm(forms.ModelForm): class Meta: model = Category fields = ['name', 'url', 'slug'] widgets = { 'name': forms.Textarea, 'url': forms.TextInput(attrs={'class': 'url'}) } labels = { 'name': 'Title', } help_texts = { 'slug': 'Watch out! Letters, numbers, underscores and hyphens only.', } error_messages = { 'slug': { 'invalid': ( "Didn't you read the help text? " "We said letters, numbers, underscores and hyphens only!" ) } } class TestFieldOverridesTroughFormMeta(TestCase): def test_widget_overrides(self): form = FieldOverridesTroughFormMetaForm() self.assertHTMLEqual( str(form['name']), '', ) self.assertHTMLEqual( str(form['url']), '', ) self.assertHTMLEqual( str(form['slug']), '', ) def test_label_overrides(self): form = FieldOverridesTroughFormMetaForm() self.assertHTMLEqual( str(form['name'].label_tag()), '', ) self.assertHTMLEqual( str(form['url'].label_tag()), '', ) self.assertHTMLEqual( str(form['slug'].label_tag()), '', ) def test_help_text_overrides(self): form = FieldOverridesTroughFormMetaForm() self.assertEqual( form['slug'].help_text, 'Watch out! Letters, numbers, underscores and hyphens only.', ) def test_error_messages_overrides(self): form = FieldOverridesTroughFormMetaForm(data={ 'name': 'Category', 'url': '/category/', 'slug': '!%#*@', }) form.full_clean() error = [ "Didn't you read the help text? " "We said letters, numbers, underscores and hyphens only!", ] self.assertEqual(form.errors, {'slug': error}) class IncompleteCategoryFormWithFields(forms.ModelForm): """ A form that replaces the model's url field with a custom one. This should prevent the model field's validation from being called. """ url = forms.CharField(required=False) class Meta: fields = ('name', 'slug') model = Category class IncompleteCategoryFormWithExclude(forms.ModelForm): """ A form that replaces the model's url field with a custom one. This should prevent the model field's validation from being called. """ url = forms.CharField(required=False) class Meta: exclude = ['url'] model = Category class ValidationTest(TestCase): def test_validates_with_replaced_field_not_specified(self): form = IncompleteCategoryFormWithFields(data={'name': 'some name', 'slug': 'some-slug'}) assert form.is_valid() def test_validates_with_replaced_field_excluded(self): form = IncompleteCategoryFormWithExclude(data={'name': 'some name', 'slug': 'some-slug'}) assert form.is_valid() def test_notrequired_overrides_notblank(self): form = CustomWriterForm({}) assert form.is_valid() # unique/unique_together validation class UniqueTest(TestCase): def setUp(self): self.writer = Writer.objects.create(name='Mike Royko') def test_simple_unique(self): form = ProductForm({'slug': 'teddy-bear-blue'}) self.assertTrue(form.is_valid()) obj = form.save() form = ProductForm({'slug': 'teddy-bear-blue'}) self.assertEqual(len(form.errors), 1) self.assertEqual(form.errors['slug'], ['Product with this Slug already exists.']) form = ProductForm({'slug': 'teddy-bear-blue'}, instance=obj) self.assertTrue(form.is_valid()) def test_unique_together(self): """ModelForm test of unique_together constraint""" form = PriceForm({'price': '6.00', 'quantity': '1'}) self.assertTrue(form.is_valid()) form.save() form = PriceForm({'price': '6.00', 'quantity': '1'}) self.assertFalse(form.is_valid()) self.assertEqual(len(form.errors), 1) self.assertEqual(form.errors['__all__'], ['Price with this Price and Quantity already exists.']) def test_unique_null(self): title = 'I May Be Wrong But I Doubt It' form = BookForm({'title': title, 'author': self.writer.pk}) self.assertTrue(form.is_valid()) form.save() form = BookForm({'title': title, 'author': self.writer.pk}) self.assertFalse(form.is_valid()) self.assertEqual(len(form.errors), 1) self.assertEqual(form.errors['__all__'], ['Book with this Title and Author already exists.']) form = BookForm({'title': title}) self.assertTrue(form.is_valid()) form.save() form = BookForm({'title': title}) self.assertTrue(form.is_valid()) def test_inherited_unique(self): title = 'Boss' Book.objects.create(title=title, author=self.writer, special_id=1) form = DerivedBookForm({'title': 'Other', 'author': self.writer.pk, 'special_id': '1', 'isbn': '12345'}) self.assertFalse(form.is_valid()) self.assertEqual(len(form.errors), 1) self.assertEqual(form.errors['special_id'], ['Book with this Special id already exists.']) def test_inherited_unique_together(self): title = 'Boss' form = BookForm({'title': title, 'author': self.writer.pk}) self.assertTrue(form.is_valid()) form.save() form = DerivedBookForm({'title': title, 'author': self.writer.pk, 'isbn': '12345'}) self.assertFalse(form.is_valid()) self.assertEqual(len(form.errors), 1) self.assertEqual(form.errors['__all__'], ['Book with this Title and Author already exists.']) def test_abstract_inherited_unique(self): title = 'Boss' isbn = '12345' dbook = DerivedBook.objects.create(title=title, author=self.writer, isbn=isbn) form = DerivedBookForm({'title': 'Other', 'author': self.writer.pk, 'isbn': isbn}) self.assertFalse(form.is_valid()) self.assertEqual(len(form.errors), 1) self.assertEqual(form.errors['isbn'], ['Derived book with this Isbn already exists.']) def test_abstract_inherited_unique_together(self): title = 'Boss' isbn = '12345' dbook = DerivedBook.objects.create(title=title, author=self.writer, isbn=isbn) form = DerivedBookForm({ 'title': 'Other', 'author': self.writer.pk, 'isbn': '9876', 'suffix1': '0', 'suffix2': '0' }) self.assertFalse(form.is_valid()) self.assertEqual(len(form.errors), 1) self.assertEqual(form.errors['__all__'], ['Derived book with this Suffix1 and Suffix2 already exists.']) def test_explicitpk_unspecified(self): """Test for primary_key being in the form and failing validation.""" form = ExplicitPKForm({'key': '', 'desc': '' }) self.assertFalse(form.is_valid()) def test_explicitpk_unique(self): """Ensure keys and blank character strings are tested for uniqueness.""" form = ExplicitPKForm({'key': 'key1', 'desc': ''}) self.assertTrue(form.is_valid()) form.save() form = ExplicitPKForm({'key': 'key1', 'desc': ''}) self.assertFalse(form.is_valid()) self.assertEqual(len(form.errors), 3) self.assertEqual(form.errors['__all__'], ['Explicit pk with this Key and Desc already exists.']) self.assertEqual(form.errors['desc'], ['Explicit pk with this Desc already exists.']) self.assertEqual(form.errors['key'], ['Explicit pk with this Key already exists.']) def test_unique_for_date(self): p = Post.objects.create(title="Django 1.0 is released", slug="Django 1.0", subtitle="Finally", posted=datetime.date(2008, 9, 3)) form = PostForm({'title': "Django 1.0 is released", 'posted': '2008-09-03'}) self.assertFalse(form.is_valid()) self.assertEqual(len(form.errors), 1) self.assertEqual(form.errors['title'], ['Title must be unique for Posted date.']) form = PostForm({'title': "Work on Django 1.1 begins", 'posted': '2008-09-03'}) self.assertTrue(form.is_valid()) form = PostForm({'title': "Django 1.0 is released", 'posted': '2008-09-04'}) self.assertTrue(form.is_valid()) form = PostForm({'slug': "Django 1.0", 'posted': '2008-01-01'}) self.assertFalse(form.is_valid()) self.assertEqual(len(form.errors), 1) self.assertEqual(form.errors['slug'], ['Slug must be unique for Posted year.']) form = PostForm({'subtitle': "Finally", 'posted': '2008-09-30'}) self.assertFalse(form.is_valid()) self.assertEqual(form.errors['subtitle'], ['Subtitle must be unique for Posted month.']) form = PostForm({'subtitle': "Finally", "title": "Django 1.0 is released", "slug": "Django 1.0", 'posted': '2008-09-03'}, instance=p) self.assertTrue(form.is_valid()) form = PostForm({'title': "Django 1.0 is released"}) self.assertFalse(form.is_valid()) self.assertEqual(len(form.errors), 1) self.assertEqual(form.errors['posted'], ['This field is required.']) def test_unique_for_date_in_exclude(self): """If the date for unique_for_* constraints is excluded from the ModelForm (in this case 'posted' has editable=False, then the constraint should be ignored.""" p = DateTimePost.objects.create(title="Django 1.0 is released", slug="Django 1.0", subtitle="Finally", posted=datetime.datetime(2008, 9, 3, 10, 10, 1)) # 'title' has unique_for_date='posted' form = DateTimePostForm({'title': "Django 1.0 is released", 'posted': '2008-09-03'}) self.assertTrue(form.is_valid()) # 'slug' has unique_for_year='posted' form = DateTimePostForm({'slug': "Django 1.0", 'posted': '2008-01-01'}) self.assertTrue(form.is_valid()) # 'subtitle' has unique_for_month='posted' form = DateTimePostForm({'subtitle': "Finally", 'posted': '2008-09-30'}) self.assertTrue(form.is_valid()) def test_inherited_unique_for_date(self): p = Post.objects.create(title="Django 1.0 is released", slug="Django 1.0", subtitle="Finally", posted=datetime.date(2008, 9, 3)) form = DerivedPostForm({'title': "Django 1.0 is released", 'posted': '2008-09-03'}) self.assertFalse(form.is_valid()) self.assertEqual(len(form.errors), 1) self.assertEqual(form.errors['title'], ['Title must be unique for Posted date.']) form = DerivedPostForm({'title': "Work on Django 1.1 begins", 'posted': '2008-09-03'}) self.assertTrue(form.is_valid()) form = DerivedPostForm({'title': "Django 1.0 is released", 'posted': '2008-09-04'}) self.assertTrue(form.is_valid()) form = DerivedPostForm({'slug': "Django 1.0", 'posted': '2008-01-01'}) self.assertFalse(form.is_valid()) self.assertEqual(len(form.errors), 1) self.assertEqual(form.errors['slug'], ['Slug must be unique for Posted year.']) form = DerivedPostForm({'subtitle': "Finally", 'posted': '2008-09-30'}) self.assertFalse(form.is_valid()) self.assertEqual(form.errors['subtitle'], ['Subtitle must be unique for Posted month.']) form = DerivedPostForm({'subtitle': "Finally", "title": "Django 1.0 is released", "slug": "Django 1.0", 'posted': '2008-09-03'}, instance=p) self.assertTrue(form.is_valid()) def test_unique_for_date_with_nullable_date(self): p = FlexibleDatePost.objects.create(title="Django 1.0 is released", slug="Django 1.0", subtitle="Finally", posted=datetime.date(2008, 9, 3)) form = FlexDatePostForm({'title': "Django 1.0 is released"}) self.assertTrue(form.is_valid()) form = FlexDatePostForm({'slug': "Django 1.0"}) self.assertTrue(form.is_valid()) form = FlexDatePostForm({'subtitle': "Finally"}) self.assertTrue(form.is_valid()) form = FlexDatePostForm({'subtitle': "Finally", "title": "Django 1.0 is released", "slug": "Django 1.0"}, instance=p) self.assertTrue(form.is_valid()) class ModelToDictTests(TestCase): """ Tests for forms.models.model_to_dict """ def test_model_to_dict_many_to_many(self): 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.save() with self.assertNumQueries(1): 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): def test_base_form(self): self.assertEqual(Category.objects.count(), 0) f = BaseCategoryForm() self.assertHTMLEqual( str(f), """ """ ) self.assertHTMLEqual( str(f.as_ul()), """
  • """ ) self.assertHTMLEqual( str(f["name"]), """""") def test_auto_id(self): f = BaseCategoryForm(auto_id=False) self.assertHTMLEqual( str(f.as_ul()), """
  • Name:
  • Slug:
  • The URL:
  • """ ) def test_with_data(self): self.assertEqual(Category.objects.count(), 0) f = BaseCategoryForm({'name': 'Entertainment', 'slug': 'entertainment', 'url': 'entertainment'}) self.assertTrue(f.is_valid()) self.assertEqual(f.cleaned_data['name'], 'Entertainment') self.assertEqual(f.cleaned_data['slug'], 'entertainment') self.assertEqual(f.cleaned_data['url'], 'entertainment') c1 = f.save() # Testing wether the same object is returned from the # ORM... not the fastest way... self.assertEqual(c1, Category.objects.all()[0]) self.assertEqual(c1.name, "Entertainment") self.assertEqual(Category.objects.count(), 1) f = BaseCategoryForm({'name': "It's a test", 'slug': 'its-test', 'url': 'test'}) self.assertTrue(f.is_valid()) self.assertEqual(f.cleaned_data['name'], "It's a test") self.assertEqual(f.cleaned_data['slug'], 'its-test') self.assertEqual(f.cleaned_data['url'], 'test') c2 = f.save() # Testing wether the same object is returned from the # ORM... not the fastest way... self.assertEqual(c2, Category.objects.get(pk=c2.pk)) self.assertEqual(c2.name, "It's a test") self.assertEqual(Category.objects.count(), 2) # If you call save() with commit=False, then it will return an object that # hasn't yet been saved to the database. In this case, it's up to you to call # save() on the resulting model instance. f = BaseCategoryForm({'name': 'Third test', 'slug': 'third-test', 'url': 'third'}) self.assertEqual(f.is_valid(), True) self.assertEqual(f.cleaned_data['url'], 'third') self.assertEqual(f.cleaned_data['name'], 'Third test') self.assertEqual(f.cleaned_data['slug'], 'third-test') c3 = f.save(commit=False) self.assertEqual(c3.name, "Third test") self.assertEqual(Category.objects.count(), 2) c3.save() self.assertEqual(Category.objects.count(), 3) # If you call save() with invalid data, you'll get a ValueError. f = BaseCategoryForm({'name': '', 'slug': 'not a slug!', 'url': 'foo'}) self.assertEqual(f.errors['name'], ['This field is required.']) self.assertEqual(f.errors['slug'], ["Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens."]) self.assertEqual(f.cleaned_data, {'url': 'foo'}) with self.assertRaises(ValueError): f.save() f = BaseCategoryForm({'name': '', 'slug': '', 'url': 'foo'}) with self.assertRaises(ValueError): f.save() # Create a couple of Writers. w_royko = Writer(name='Mike Royko') w_royko.save() w_woodward = Writer(name='Bob Woodward') w_woodward.save() # ManyToManyFields are represented by a MultipleChoiceField, ForeignKeys and any # fields with the 'choices' attribute are represented by a ChoiceField. f = ArticleForm(auto_id=False) self.assertHTMLEqual(six.text_type(f), '''Headline: Slug: Pub date: Writer: Article: Categories:
    Hold down "Control", or "Command" on a Mac, to select more than one. Status:''' % (w_woodward.pk, w_royko.pk, c1.pk, c2.pk, c3.pk)) # You can restrict a form to a subset of the complete list of fields # by providing a 'fields' argument. If you try to save a # model created with such a form, you need to ensure that the fields # that are _not_ on the form have default values, or are allowed to have # a value of None. If a field isn't specified on a form, the object created # from the form can't provide a value for that field! f = PartialArticleForm(auto_id=False) self.assertHTMLEqual(six.text_type(f), '''Headline: Pub date:''') # When the ModelForm is passed an instance, that instance's current values are # inserted as 'initial' data in each Field. w = Writer.objects.get(name='Mike Royko') f = RoykoForm(auto_id=False, instance=w) self.assertHTMLEqual(six.text_type(f), '''Name:
    Use both first and last names.''') art = Article( headline='Test article', slug='test-article', pub_date=datetime.date(1988, 1, 4), writer=w, article='Hello.' ) art.save() art_id_1 = art.id self.assertEqual(art_id_1 is not None, True) f = TestArticleForm(auto_id=False, instance=art) self.assertHTMLEqual(f.as_ul(), '''
  • Headline:
  • Slug:
  • Pub date:
  • Writer:
  • Article:
  • Categories: Hold down "Control", or "Command" on a Mac, to select more than one.
  • Status:
  • ''' % (w_woodward.pk, w_royko.pk, c1.pk, c2.pk, c3.pk)) f = TestArticleForm({ 'headline': 'Test headline', 'slug': 'test-headline', 'pub_date': '1984-02-06', 'writer': six.text_type(w_royko.pk), 'article': 'Hello.' }, instance=art) self.assertEqual(f.errors, {}) self.assertEqual(f.is_valid(), True) test_art = f.save() self.assertEqual(test_art.id == art_id_1, True) test_art = Article.objects.get(id=art_id_1) self.assertEqual(test_art.headline, 'Test headline') # You can create a form over a subset of the available fields # by specifying a 'fields' argument to form_for_instance. f = PartialArticleFormWithSlug({ 'headline': 'New headline', 'slug': 'new-headline', 'pub_date': '1988-01-04' }, auto_id=False, instance=art) self.assertHTMLEqual(f.as_ul(), '''
  • Headline:
  • Slug:
  • Pub date:
  • ''') self.assertEqual(f.is_valid(), True) new_art = f.save() self.assertEqual(new_art.id == art_id_1, True) new_art = Article.objects.get(id=art_id_1) self.assertEqual(new_art.headline, 'New headline') # Add some categories and test the many-to-many form output. self.assertQuerysetEqual(new_art.categories.all(), []) new_art.categories.add(Category.objects.get(name='Entertainment')) self.assertQuerysetEqual(new_art.categories.all(), ["Entertainment"]) f = TestArticleForm(auto_id=False, instance=new_art) self.assertHTMLEqual(f.as_ul(), '''
  • Headline:
  • Slug:
  • Pub date:
  • Writer:
  • Article:
  • Categories: Hold down "Control", or "Command" on a Mac, to select more than one.
  • Status:
  • ''' % (w_woodward.pk, w_royko.pk, c1.pk, c2.pk, c3.pk)) # Initial values can be provided for model forms f = TestArticleForm( auto_id=False, initial={ 'headline': 'Your headline here', 'categories': [str(c1.id), str(c2.id)] }) self.assertHTMLEqual(f.as_ul(), '''
  • Headline:
  • Slug:
  • Pub date:
  • Writer:
  • Article:
  • Categories: Hold down "Control", or "Command" on a Mac, to select more than one.
  • Status:
  • ''' % (w_woodward.pk, w_royko.pk, c1.pk, c2.pk, c3.pk)) f = TestArticleForm({ 'headline': 'New headline', 'slug': 'new-headline', 'pub_date': '1988-01-04', 'writer': six.text_type(w_royko.pk), 'article': 'Hello.', 'categories': [six.text_type(c1.id), six.text_type(c2.id)] }, instance=new_art) new_art = f.save() self.assertEqual(new_art.id == art_id_1, True) new_art = Article.objects.get(id=art_id_1) self.assertQuerysetEqual(new_art.categories.order_by('name'), ["Entertainment", "It's a test"]) # Now, submit form data with no categories. This deletes the existing categories. f = TestArticleForm({'headline': 'New headline', 'slug': 'new-headline', 'pub_date': '1988-01-04', 'writer': six.text_type(w_royko.pk), 'article': 'Hello.'}, instance=new_art) new_art = f.save() self.assertEqual(new_art.id == art_id_1, True) new_art = Article.objects.get(id=art_id_1) self.assertQuerysetEqual(new_art.categories.all(), []) # Create a new article, with categories, via the form. f = ArticleForm({'headline': 'The walrus was Paul', 'slug': 'walrus-was-paul', 'pub_date': '1967-11-01', 'writer': six.text_type(w_royko.pk), 'article': 'Test.', 'categories': [six.text_type(c1.id), six.text_type(c2.id)]}) new_art = f.save() art_id_2 = new_art.id self.assertEqual(art_id_2 not in (None, art_id_1), True) new_art = Article.objects.get(id=art_id_2) self.assertQuerysetEqual(new_art.categories.order_by('name'), ["Entertainment", "It's a test"]) # Create a new article, with no categories, via the form. f = ArticleForm({'headline': 'The walrus was Paul', 'slug': 'walrus-was-paul', 'pub_date': '1967-11-01', 'writer': six.text_type(w_royko.pk), 'article': 'Test.'}) new_art = f.save() art_id_3 = new_art.id self.assertEqual(art_id_3 not in (None, art_id_1, art_id_2), True) new_art = Article.objects.get(id=art_id_3) self.assertQuerysetEqual(new_art.categories.all(), []) # Create a new article, with categories, via the form, but use commit=False. # The m2m data won't be saved until save_m2m() is invoked on the form. f = ArticleForm({'headline': 'The walrus was Paul', 'slug': 'walrus-was-paul', 'pub_date': '1967-11-01', 'writer': six.text_type(w_royko.pk), 'article': 'Test.', 'categories': [six.text_type(c1.id), six.text_type(c2.id)]}) new_art = f.save(commit=False) # Manually save the instance new_art.save() art_id_4 = new_art.id self.assertEqual(art_id_4 not in (None, art_id_1, art_id_2, art_id_3), True) # The instance doesn't have m2m data yet new_art = Article.objects.get(id=art_id_4) self.assertQuerysetEqual(new_art.categories.all(), []) # Save the m2m data on the form f.save_m2m() self.assertQuerysetEqual(new_art.categories.order_by('name'), ["Entertainment", "It's a test"]) # Here, we define a custom ModelForm. Because it happens to have the same fields as # the Category model, we can just call the form's save() to apply its changes to an # existing Category instance. cat = Category.objects.get(name='Third test') self.assertEqual(cat.name, "Third test") self.assertEqual(cat.id == c3.id, True) form = ShortCategory({'name': 'Third', 'slug': 'third', 'url': '3rd'}, instance=cat) self.assertEqual(form.save().name, 'Third') self.assertEqual(Category.objects.get(id=c3.id).name, 'Third') # Here, we demonstrate that choices for a ForeignKey ChoiceField are determined # at runtime, based on the data in the database when the form is displayed, not # the data in the database when the form is instantiated. f = ArticleForm(auto_id=False) self.assertHTMLEqual(f.as_ul(), '''
  • Headline:
  • Slug:
  • Pub date:
  • Writer:
  • Article:
  • Categories: Hold down "Control", or "Command" on a Mac, to select more than one.
  • Status:
  • ''' % (w_woodward.pk, w_royko.pk, c1.pk, c2.pk, c3.pk)) c4 = Category.objects.create(name='Fourth', url='4th') self.assertEqual(c4.name, 'Fourth') w_bernstein = Writer.objects.create(name='Carl Bernstein') self.assertEqual(w_bernstein.name, 'Carl Bernstein') self.assertHTMLEqual(f.as_ul(), '''
  • Headline:
  • Slug:
  • Pub date:
  • Writer:
  • Article:
  • Categories: Hold down "Control", or "Command" on a Mac, to select more than one.
  • Status:
  • ''' % (w_woodward.pk, w_bernstein.pk, w_royko.pk, c1.pk, c2.pk, c3.pk, c4.pk)) # ModelChoiceField ############################################################ f = forms.ModelChoiceField(Category.objects.all()) self.assertEqual(list(f.choices), [ ('', '---------'), (c1.pk, 'Entertainment'), (c2.pk, "It's a test"), (c3.pk, 'Third'), (c4.pk, 'Fourth')]) self.assertEqual(5, len(f.choices)) with self.assertRaises(ValidationError): f.clean('') with self.assertRaises(ValidationError): f.clean(None) with self.assertRaises(ValidationError): f.clean(0) self.assertEqual(f.clean(c3.id).name, 'Third') self.assertEqual(f.clean(c2.id).name, "It's a test") # Add a Category object *after* the ModelChoiceField has already been # instantiated. This proves clean() checks the database during clean() rather # than caching it at time of instantiation. c5 = Category.objects.create(name='Fifth', url='5th') self.assertEqual(c5.name, 'Fifth') self.assertEqual(f.clean(c5.id).name, 'Fifth') # Delete a Category object *after* the ModelChoiceField has already been # instantiated. This proves clean() checks the database during clean() rather # than caching it at time of instantiation. Category.objects.get(url='5th').delete() with self.assertRaises(ValidationError): f.clean(c5.id) f = forms.ModelChoiceField(Category.objects.filter(pk=c1.id), required=False) self.assertEqual(f.clean(''), None) f.clean('') self.assertEqual(f.clean(str(c1.id)).name, "Entertainment") with self.assertRaises(ValidationError): f.clean('100') # queryset can be changed after the field is created. f.queryset = Category.objects.exclude(name='Fourth') self.assertEqual(list(f.choices), [ ('', '---------'), (c1.pk, 'Entertainment'), (c2.pk, "It's a test"), (c3.pk, 'Third')]) self.assertEqual(f.clean(c3.id).name, 'Third') with self.assertRaises(ValidationError): f.clean(c4.id) # check that we can safely iterate choices repeatedly gen_one = list(f.choices) gen_two = f.choices self.assertEqual(gen_one[2], (c2.pk, "It's a test")) self.assertEqual(list(gen_two), [ ('', '---------'), (c1.pk, 'Entertainment'), (c2.pk, "It's a test"), (c3.pk, 'Third')]) # check that we can override the label_from_instance method to print custom labels (#4620) f.queryset = Category.objects.all() f.label_from_instance = lambda obj: "category " + str(obj) self.assertEqual(list(f.choices), [ ('', '---------'), (c1.pk, 'category Entertainment'), (c2.pk, "category It's a test"), (c3.pk, 'category Third'), (c4.pk, 'category Fourth')]) # ModelMultipleChoiceField #################################################### f = forms.ModelMultipleChoiceField(Category.objects.all()) self.assertEqual(list(f.choices), [ (c1.pk, 'Entertainment'), (c2.pk, "It's a test"), (c3.pk, 'Third'), (c4.pk, 'Fourth')]) with self.assertRaises(ValidationError): f.clean(None) with self.assertRaises(ValidationError): f.clean([]) self.assertQuerysetEqual(f.clean([c1.id]), ["Entertainment"]) self.assertQuerysetEqual(f.clean([c2.id]), ["It's a test"]) self.assertQuerysetEqual(f.clean([str(c1.id)]), ["Entertainment"]) self.assertQuerysetEqual(f.clean([str(c1.id), str(c2.id)]), ["Entertainment", "It's a test"], ordered=False) self.assertQuerysetEqual(f.clean([c1.id, str(c2.id)]), ["Entertainment", "It's a test"], ordered=False) self.assertQuerysetEqual(f.clean((c1.id, str(c2.id))), ["Entertainment", "It's a test"], ordered=False) with self.assertRaises(ValidationError): f.clean(['100']) with self.assertRaises(ValidationError): f.clean('hello') with self.assertRaises(ValidationError): f.clean(['fail']) # Add a Category object *after* the ModelMultipleChoiceField has already been # instantiated. This proves clean() checks the database during clean() rather # than caching it at time of instantiation. # Note, we are using an id of 1006 here since tests that run before # this may create categories with primary keys up to 6. Use # a number that is will not conflict. c6 = Category.objects.create(id=1006, name='Sixth', url='6th') self.assertEqual(c6.name, 'Sixth') self.assertQuerysetEqual(f.clean([c6.id]), ["Sixth"]) # Delete a Category object *after* the ModelMultipleChoiceField has already been # instantiated. This proves clean() checks the database during clean() rather # than caching it at time of instantiation. Category.objects.get(url='6th').delete() with self.assertRaises(ValidationError): f.clean([c6.id]) f = forms.ModelMultipleChoiceField(Category.objects.all(), required=False) self.assertIsInstance(f.clean([]), EmptyQuerySet) self.assertIsInstance(f.clean(()), EmptyQuerySet) with self.assertRaises(ValidationError): f.clean(['10']) with self.assertRaises(ValidationError): f.clean([str(c3.id), '10']) with self.assertRaises(ValidationError): f.clean([str(c1.id), '10']) # queryset can be changed after the field is created. f.queryset = Category.objects.exclude(name='Fourth') self.assertEqual(list(f.choices), [ (c1.pk, 'Entertainment'), (c2.pk, "It's a test"), (c3.pk, 'Third')]) self.assertQuerysetEqual(f.clean([c3.id]), ["Third"]) with self.assertRaises(ValidationError): f.clean([c4.id]) with self.assertRaises(ValidationError): f.clean([str(c3.id), str(c4.id)]) f.queryset = Category.objects.all() f.label_from_instance = lambda obj: "multicategory " + str(obj) self.assertEqual(list(f.choices), [ (c1.pk, 'multicategory Entertainment'), (c2.pk, "multicategory It's a test"), (c3.pk, 'multicategory Third'), (c4.pk, 'multicategory Fourth')]) # OneToOneField ############################################################### self.assertEqual(list(ImprovedArticleForm.base_fields), ['article']) self.assertEqual(list(ImprovedArticleWithParentLinkForm.base_fields), []) bw = BetterWriter(name='Joe Better', score=10) bw.save() self.assertEqual(sorted(model_to_dict(bw)), ['id', 'name', 'score', 'writer_ptr']) form = BetterWriterForm({'name': 'Some Name', 'score': 12}) self.assertEqual(form.is_valid(), True) bw2 = form.save() bw2.delete() form = WriterProfileForm() self.assertHTMLEqual(form.as_p(), '''

    ''' % (w_woodward.pk, w_bernstein.pk, bw.pk, w_royko.pk)) data = { 'writer': six.text_type(w_woodward.pk), 'age': '65', } form = WriterProfileForm(data) instance = form.save() self.assertEqual(six.text_type(instance), 'Bob Woodward is 65') form = WriterProfileForm(instance=instance) self.assertHTMLEqual(form.as_p(), '''

    ''' % (w_woodward.pk, w_bernstein.pk, bw.pk, w_royko.pk)) def test_show_hidden_initial_changed_queries_efficiently(self): class WriterForm(forms.Form): persons = forms.ModelMultipleChoiceField( show_hidden_initial=True, queryset=Writer.objects.all()) writers = (Writer.objects.create(name=str(x)) for x in range(0, 50)) writer_pks = tuple(x.pk for x in writers) form = WriterForm(data={'initial-persons': writer_pks}) with self.assertNumQueries(1): self.assertTrue(form.has_changed()) def test_clean_does_deduplicate_values(self): class WriterForm(forms.Form): persons = forms.ModelMultipleChoiceField(queryset=Writer.objects.all()) person1 = Writer.objects.create(name="Person 1") form = WriterForm(data={}) queryset = form.fields['persons'].clean([str(person1.pk)] * 50) sql, params = queryset.query.sql_with_params() self.assertEqual(len(params), 1) def test_file_field(self): # Test conditions when files is either not given or empty. f = TextFileForm(data={'description': 'Assistance'}) self.assertEqual(f.is_valid(), False) f = TextFileForm(data={'description': 'Assistance'}, files={}) self.assertEqual(f.is_valid(), False) # Upload a file and ensure it all works as expected. f = TextFileForm( data={'description': 'Assistance'}, files={'file': SimpleUploadedFile('test1.txt', b'hello world')}) self.assertEqual(f.is_valid(), True) self.assertEqual(type(f.cleaned_data['file']), SimpleUploadedFile) instance = f.save() self.assertEqual(instance.file.name, 'tests/test1.txt') instance.file.delete() f = TextFileForm( data={'description': 'Assistance'}, files={'file': SimpleUploadedFile('test1.txt', b'hello world')}) self.assertEqual(f.is_valid(), True) self.assertEqual(type(f.cleaned_data['file']), SimpleUploadedFile) instance = f.save() self.assertEqual(instance.file.name, 'tests/test1.txt') # Check if the max_length attribute has been inherited from the model. f = TextFileForm( data={'description': 'Assistance'}, files={'file': SimpleUploadedFile('test-maxlength.txt', b'hello world')}) self.assertEqual(f.is_valid(), False) # Edit an instance that already has the file defined in the model. This will not # save the file again, but leave it exactly as it is. f = TextFileForm( data={'description': 'Assistance'}, instance=instance) self.assertEqual(f.is_valid(), True) self.assertEqual(f.cleaned_data['file'].name, 'tests/test1.txt') instance = f.save() self.assertEqual(instance.file.name, 'tests/test1.txt') # Delete the current file since this is not done by Django. instance.file.delete() # Override the file by uploading a new one. f = TextFileForm( data={'description': 'Assistance'}, files={'file': SimpleUploadedFile('test2.txt', b'hello world')}, instance=instance) self.assertEqual(f.is_valid(), True) instance = f.save() self.assertEqual(instance.file.name, 'tests/test2.txt') # Delete the current file since this is not done by Django. instance.file.delete() f = TextFileForm( data={'description': 'Assistance'}, files={'file': SimpleUploadedFile('test2.txt', b'hello world')}) self.assertEqual(f.is_valid(), True) instance = f.save() self.assertEqual(instance.file.name, 'tests/test2.txt') # Delete the current file since this is not done by Django. instance.file.delete() instance.delete() # Test the non-required FileField f = TextFileForm(data={'description': 'Assistance'}) f.fields['file'].required = False self.assertEqual(f.is_valid(), True) instance = f.save() self.assertEqual(instance.file.name, '') f = TextFileForm( data={'description': 'Assistance'}, files={'file': SimpleUploadedFile('test3.txt', b'hello world')}, instance=instance) self.assertEqual(f.is_valid(), True) instance = f.save() self.assertEqual(instance.file.name, 'tests/test3.txt') # Instance can be edited w/out re-uploading the file and existing file should be preserved. f = TextFileForm( data={'description': 'New Description'}, instance=instance) f.fields['file'].required = False self.assertEqual(f.is_valid(), True) instance = f.save() self.assertEqual(instance.description, 'New Description') self.assertEqual(instance.file.name, 'tests/test3.txt') # Delete the current file since this is not done by Django. instance.file.delete() instance.delete() f = TextFileForm( data={'description': 'Assistance'}, files={'file': SimpleUploadedFile('test3.txt', b'hello world')}) self.assertEqual(f.is_valid(), True) instance = f.save() self.assertEqual(instance.file.name, 'tests/test3.txt') # Delete the current file since this is not done by Django. instance.file.delete() instance.delete() def test_big_integer_field(self): bif = BigIntForm({'biggie': '-9223372036854775808'}) self.assertEqual(bif.is_valid(), True) bif = BigIntForm({'biggie': '-9223372036854775809'}) self.assertEqual(bif.is_valid(), False) self.assertEqual(bif.errors, {'biggie': ['Ensure this value is greater than or equal to -9223372036854775808.']}) bif = BigIntForm({'biggie': '9223372036854775807'}) self.assertEqual(bif.is_valid(), True) bif = BigIntForm({'biggie': '9223372036854775808'}) self.assertEqual(bif.is_valid(), False) self.assertEqual(bif.errors, {'biggie': ['Ensure this value is less than or equal to 9223372036854775807.']}) @skipUnless(test_images, "PIL not installed") def test_image_field(self): # ImageField and FileField are nearly identical, but they differ slighty when # it comes to validation. This specifically tests that #6302 is fixed for # both file fields and image fields. with open(os.path.join(os.path.dirname(upath(__file__)), "test.png"), 'rb') as fp: image_data = fp.read() with open(os.path.join(os.path.dirname(upath(__file__)), "test2.png"), 'rb') as fp: image_data2 = fp.read() f = ImageFileForm( data={'description': 'An image'}, files={'image': SimpleUploadedFile('test.png', image_data)}) self.assertEqual(f.is_valid(), True) self.assertEqual(type(f.cleaned_data['image']), SimpleUploadedFile) instance = f.save() self.assertEqual(instance.image.name, 'tests/test.png') self.assertEqual(instance.width, 16) self.assertEqual(instance.height, 16) # Delete the current file since this is not done by Django, but don't save # because the dimension fields are not null=True. instance.image.delete(save=False) f = ImageFileForm( data={'description': 'An image'}, files={'image': SimpleUploadedFile('test.png', image_data)}) self.assertEqual(f.is_valid(), True) self.assertEqual(type(f.cleaned_data['image']), SimpleUploadedFile) instance = f.save() self.assertEqual(instance.image.name, 'tests/test.png') self.assertEqual(instance.width, 16) self.assertEqual(instance.height, 16) # Edit an instance that already has the (required) image defined in the model. This will not # save the image again, but leave it exactly as it is. f = ImageFileForm(data={'description': 'Look, it changed'}, instance=instance) self.assertEqual(f.is_valid(), True) self.assertEqual(f.cleaned_data['image'].name, 'tests/test.png') instance = f.save() self.assertEqual(instance.image.name, 'tests/test.png') self.assertEqual(instance.height, 16) self.assertEqual(instance.width, 16) # Delete the current file since this is not done by Django, but don't save # because the dimension fields are not null=True. instance.image.delete(save=False) # Override the file by uploading a new one. f = ImageFileForm( data={'description': 'Changed it'}, files={'image': SimpleUploadedFile('test2.png', image_data2)}, instance=instance) self.assertEqual(f.is_valid(), True) instance = f.save() self.assertEqual(instance.image.name, 'tests/test2.png') self.assertEqual(instance.height, 32) self.assertEqual(instance.width, 48) # Delete the current file since this is not done by Django, but don't save # because the dimension fields are not null=True. instance.image.delete(save=False) instance.delete() f = ImageFileForm( data={'description': 'Changed it'}, files={'image': SimpleUploadedFile('test2.png', image_data2)}) self.assertEqual(f.is_valid(), True) instance = f.save() self.assertEqual(instance.image.name, 'tests/test2.png') self.assertEqual(instance.height, 32) self.assertEqual(instance.width, 48) # Delete the current file since this is not done by Django, but don't save # because the dimension fields are not null=True. instance.image.delete(save=False) instance.delete() # Test the non-required ImageField # Note: In Oracle, we expect a null ImageField to return '' instead of # None. if connection.features.interprets_empty_strings_as_nulls: expected_null_imagefield_repr = '' else: expected_null_imagefield_repr = None f = OptionalImageFileForm(data={'description': 'Test'}) self.assertEqual(f.is_valid(), True) instance = f.save() self.assertEqual(instance.image.name, expected_null_imagefield_repr) self.assertEqual(instance.width, None) self.assertEqual(instance.height, None) f = OptionalImageFileForm( data={'description': 'And a final one'}, files={'image': SimpleUploadedFile('test3.png', image_data)}, instance=instance) self.assertEqual(f.is_valid(), True) instance = f.save() self.assertEqual(instance.image.name, 'tests/test3.png') self.assertEqual(instance.width, 16) self.assertEqual(instance.height, 16) # Editing the instance without re-uploading the image should not affect the image or its width/height properties f = OptionalImageFileForm( data={'description': 'New Description'}, instance=instance) self.assertEqual(f.is_valid(), True) instance = f.save() self.assertEqual(instance.description, 'New Description') self.assertEqual(instance.image.name, 'tests/test3.png') self.assertEqual(instance.width, 16) self.assertEqual(instance.height, 16) # Delete the current file since this is not done by Django. instance.image.delete() instance.delete() f = OptionalImageFileForm( data={'description': 'And a final one'}, files={'image': SimpleUploadedFile('test4.png', image_data2)} ) self.assertEqual(f.is_valid(), True) instance = f.save() self.assertEqual(instance.image.name, 'tests/test4.png') self.assertEqual(instance.width, 48) self.assertEqual(instance.height, 32) instance.delete() # Test callable upload_to behavior that's dependent on the value of another field in the model f = ImageFileForm( data={'description': 'And a final one', 'path': 'foo'}, files={'image': SimpleUploadedFile('test4.png', image_data)}) self.assertEqual(f.is_valid(), True) instance = f.save() self.assertEqual(instance.image.name, 'foo/test4.png') instance.delete() def test_media_on_modelform(self): # Similar to a regular Form class you can define custom media to be used on # the ModelForm. f = ModelFormWithMedia() self.assertHTMLEqual(six.text_type(f.media), ''' ''') f = CommaSeparatedIntegerForm({'field': '1,2,3'}) self.assertEqual(f.is_valid(), True) self.assertEqual(f.cleaned_data, {'field': '1,2,3'}) f = CommaSeparatedIntegerForm({'field': '1a,2'}) self.assertEqual(f.errors, {'field': ['Enter only digits separated by commas.']}) f = CommaSeparatedIntegerForm({'field': ',,,,'}) self.assertEqual(f.is_valid(), True) self.assertEqual(f.cleaned_data, {'field': ',,,,'}) f = CommaSeparatedIntegerForm({'field': '1.2'}) self.assertEqual(f.errors, {'field': ['Enter only digits separated by commas.']}) f = CommaSeparatedIntegerForm({'field': '1,a,2'}) self.assertEqual(f.errors, {'field': ['Enter only digits separated by commas.']}) f = CommaSeparatedIntegerForm({'field': '1,,2'}) self.assertEqual(f.is_valid(), True) self.assertEqual(f.cleaned_data, {'field': '1,,2'}) f = CommaSeparatedIntegerForm({'field': '1'}) self.assertEqual(f.is_valid(), True) self.assertEqual(f.cleaned_data, {'field': '1'}) # This Price instance generated by this form is not valid because the quantity # field is required, but the form is valid because the field is excluded from # the form. This is for backwards compatibility. form = PriceFormWithoutQuantity({'price': '6.00'}) self.assertEqual(form.is_valid(), True) price = form.save(commit=False) with self.assertRaises(ValidationError): price.full_clean() # The form should not validate fields that it doesn't contain even if they are # specified using 'fields', not 'exclude'. class Meta: model = Price fields = ('price',) form = PriceFormWithoutQuantity({'price': '6.00'}) self.assertEqual(form.is_valid(), True) # The form should still have an instance of a model that is not complete and # not saved into a DB yet. self.assertEqual(form.instance.price, Decimal('6.00')) self.assertEqual(form.instance.quantity is None, True) self.assertEqual(form.instance.pk is None, True) # Choices on CharField and IntegerField f = ArticleForm() with self.assertRaises(ValidationError): f.fields['status'].clean('42') f = ArticleStatusForm() with self.assertRaises(ValidationError): f.fields['status'].clean('z') def test_foreignkeys_which_use_to_field(self): apple = Inventory.objects.create(barcode=86, name='Apple') pear = Inventory.objects.create(barcode=22, name='Pear') core = Inventory.objects.create(barcode=87, name='Core', parent=apple) field = forms.ModelChoiceField(Inventory.objects.all(), to_field_name='barcode') self.assertEqual(tuple(field.choices), ( ('', '---------'), (86, 'Apple'), (87, 'Core'), (22, 'Pear'))) form = InventoryForm(instance=core) self.assertHTMLEqual(six.text_type(form['parent']), '''''') data = model_to_dict(core) data['parent'] = '22' form = InventoryForm(data=data, instance=core) core = form.save() self.assertEqual(core.parent.name, 'Pear') class CategoryForm(forms.ModelForm): description = forms.CharField() class Meta: model = Category fields = ['description', 'url'] self.assertEqual(list(CategoryForm.base_fields), ['description', 'url']) self.assertHTMLEqual(six.text_type(CategoryForm()), ''' ''') # to_field_name should also work on ModelMultipleChoiceField ################## field = forms.ModelMultipleChoiceField(Inventory.objects.all(), to_field_name='barcode') self.assertEqual(tuple(field.choices), ((86, 'Apple'), (87, 'Core'), (22, 'Pear'))) self.assertQuerysetEqual(field.clean([86]), ['Apple']) form = SelectInventoryForm({'items': [87, 22]}) self.assertEqual(form.is_valid(), True) self.assertEqual(len(form.cleaned_data), 1) self.assertQuerysetEqual(form.cleaned_data['items'], ['Core', 'Pear']) def test_model_field_that_returns_none_to_exclude_itself_with_explicit_fields(self): self.assertEqual(list(CustomFieldForExclusionForm.base_fields), ['name']) self.assertHTMLEqual(six.text_type(CustomFieldForExclusionForm()), '''''') def test_iterable_model_m2m(self) : colour = Colour.objects.create(name='Blue') form = ColourfulItemForm() self.maxDiff = 1024 self.assertHTMLEqual( form.as_p(), """

    Hold down "Control", or "Command" on a Mac, to select more than one.

    """ % {'blue_pk': colour.pk}) def test_custom_error_messages(self) : data = {'name1': '@#$!!**@#$', 'name2': '@#$!!**@#$'} errors = CustomErrorMessageForm(data).errors self.assertHTMLEqual( str(errors['name1']), '
    • Form custom error message.
    ' ) self.assertHTMLEqual( str(errors['name2']), '
    • Model custom error message.
    ' ) class M2mHelpTextTest(TestCase): """Tests for ticket #9321.""" def test_multiple_widgets(self): """Help text of different widgets for ManyToManyFields model fields""" dreaded_help_text = ' Hold down "Control", or "Command" on a Mac, to select more than one.' # Default widget (SelectMultiple): std_form = StatusNoteForm() self.assertInHTML(dreaded_help_text, std_form.as_p()) # Overridden widget (CheckboxSelectMultiple, a subclass of # SelectMultiple but with a UI that doesn't involve Control/Command # keystrokes to extend selection): form = StatusNoteCBM2mForm() html = form.as_p() self.assertInHTML('
      ', html) self.assertInHTML(dreaded_help_text, html, count=0) Django-1.6.11/tests/model_forms/models.py0000664000175000017500000002237712502407523017730 0ustar timtim00000000000000""" XX. Generating HTML forms from models This is mostly just a reworking of the ``form_for_model``/``form_for_instance`` tests to use ``ModelForm``. As such, the text may not make sense in all cases, and the examples are probably a poor fit for the ``ModelForm`` syntax. In other words, most of these tests should be rewritten. """ from __future__ import unicode_literals import os import tempfile from django.core import validators from django.core.exceptions import ImproperlyConfigured from django.core.files.storage import FileSystemStorage from django.db import models from django.utils import six from django.utils.encoding import python_2_unicode_compatible temp_storage_dir = tempfile.mkdtemp(dir=os.environ['DJANGO_TEST_TEMP_DIR']) temp_storage = FileSystemStorage(temp_storage_dir) ARTICLE_STATUS = ( (1, 'Draft'), (2, 'Pending'), (3, 'Live'), ) ARTICLE_STATUS_CHAR = ( ('d', 'Draft'), ('p', 'Pending'), ('l', 'Live'), ) @python_2_unicode_compatible class Category(models.Model): name = models.CharField(max_length=20) slug = models.SlugField(max_length=20) url = models.CharField('The URL', max_length=40) def __str__(self): return self.name def __repr__(self): return self.__str__() @python_2_unicode_compatible class Writer(models.Model): name = models.CharField(max_length=50, help_text='Use both first and last names.') class Meta: ordering = ('name',) def __str__(self): return self.name @python_2_unicode_compatible class Article(models.Model): headline = models.CharField(max_length=50) slug = models.SlugField() pub_date = models.DateField() created = models.DateField(editable=False) writer = models.ForeignKey(Writer) article = models.TextField() categories = models.ManyToManyField(Category, blank=True) status = models.PositiveIntegerField(choices=ARTICLE_STATUS, blank=True, null=True) def save(self): import datetime if not self.id: self.created = datetime.date.today() return super(Article, self).save() def __str__(self): return self.headline class ImprovedArticle(models.Model): article = models.OneToOneField(Article) class ImprovedArticleWithParentLink(models.Model): article = models.OneToOneField(Article, parent_link=True) class BetterWriter(Writer): score = models.IntegerField() @python_2_unicode_compatible class WriterProfile(models.Model): writer = models.OneToOneField(Writer, primary_key=True) age = models.PositiveIntegerField() def __str__(self): return "%s is %s" % (self.writer, self.age) @python_2_unicode_compatible class TextFile(models.Model): description = models.CharField(max_length=20) file = models.FileField(storage=temp_storage, upload_to='tests', max_length=15) def __str__(self): return self.description try: from django.utils.image import Image test_images = True @python_2_unicode_compatible class ImageFile(models.Model): def custom_upload_path(self, filename): path = self.path or 'tests' return '%s/%s' % (path, filename) description = models.CharField(max_length=20) # Deliberately put the image field *after* the width/height fields to # trigger the bug in #10404 with width/height not getting assigned. width = models.IntegerField(editable=False) height = models.IntegerField(editable=False) image = models.ImageField(storage=temp_storage, upload_to=custom_upload_path, width_field='width', height_field='height') path = models.CharField(max_length=16, blank=True, default='') def __str__(self): return self.description @python_2_unicode_compatible class OptionalImageFile(models.Model): def custom_upload_path(self, filename): path = self.path or 'tests' return '%s/%s' % (path, filename) description = models.CharField(max_length=20) image = models.ImageField(storage=temp_storage, upload_to=custom_upload_path, width_field='width', height_field='height', blank=True, null=True) width = models.IntegerField(editable=False, null=True) height = models.IntegerField(editable=False, null=True) path = models.CharField(max_length=16, blank=True, default='') def __str__(self): return self.description except ImproperlyConfigured: test_images = False @python_2_unicode_compatible class CommaSeparatedInteger(models.Model): field = models.CommaSeparatedIntegerField(max_length=20) def __str__(self): return self.field @python_2_unicode_compatible class Product(models.Model): slug = models.SlugField(unique=True) def __str__(self): return self.slug @python_2_unicode_compatible class Price(models.Model): price = models.DecimalField(max_digits=10, decimal_places=2) quantity = models.PositiveIntegerField() def __str__(self): return "%s for %s" % (self.quantity, self.price) class Meta: unique_together = (('price', 'quantity'),) class ArticleStatus(models.Model): status = models.CharField(max_length=2, choices=ARTICLE_STATUS_CHAR, blank=True, null=True) @python_2_unicode_compatible class Inventory(models.Model): barcode = models.PositiveIntegerField(unique=True) parent = models.ForeignKey('self', to_field='barcode', blank=True, null=True) name = models.CharField(blank=False, max_length=20) class Meta: ordering = ('name',) def __str__(self): return self.name def __repr__(self): return self.__str__() class Book(models.Model): title = models.CharField(max_length=40) author = models.ForeignKey(Writer, blank=True, null=True) special_id = models.IntegerField(blank=True, null=True, unique=True) class Meta: unique_together = ('title', 'author') class BookXtra(models.Model): isbn = models.CharField(max_length=16, unique=True) suffix1 = models.IntegerField(blank=True, default=0) suffix2 = models.IntegerField(blank=True, default=0) class Meta: unique_together = (('suffix1', 'suffix2')) abstract = True class DerivedBook(Book, BookXtra): pass @python_2_unicode_compatible class ExplicitPK(models.Model): key = models.CharField(max_length=20, primary_key=True) desc = models.CharField(max_length=20, blank=True, unique=True) class Meta: unique_together = ('key', 'desc') def __str__(self): return self.key @python_2_unicode_compatible class Post(models.Model): title = models.CharField(max_length=50, unique_for_date='posted', blank=True) slug = models.CharField(max_length=50, unique_for_year='posted', blank=True) subtitle = models.CharField(max_length=50, unique_for_month='posted', blank=True) posted = models.DateField() def __str__(self): return self.title @python_2_unicode_compatible class DateTimePost(models.Model): title = models.CharField(max_length=50, unique_for_date='posted', blank=True) slug = models.CharField(max_length=50, unique_for_year='posted', blank=True) subtitle = models.CharField(max_length=50, unique_for_month='posted', blank=True) posted = models.DateTimeField(editable=False) def __str__(self): return self.title class DerivedPost(Post): pass @python_2_unicode_compatible class BigInt(models.Model): biggie = models.BigIntegerField() def __str__(self): return six.text_type(self.biggie) class MarkupField(models.CharField): def __init__(self, *args, **kwargs): kwargs["max_length"] = 20 super(MarkupField, self).__init__(*args, **kwargs) def formfield(self, **kwargs): # don't allow this field to be used in form (real use-case might be # that you know the markup will always be X, but it is among an app # that allows the user to say it could be something else) # regressed at r10062 return None class CustomFieldForExclusionModel(models.Model): name = models.CharField(max_length=10) markup = MarkupField() class FlexibleDatePost(models.Model): title = models.CharField(max_length=50, unique_for_date='posted', blank=True) slug = models.CharField(max_length=50, unique_for_year='posted', blank=True) subtitle = models.CharField(max_length=50, unique_for_month='posted', blank=True) posted = models.DateField(blank=True, null=True) @python_2_unicode_compatible class Colour(models.Model): name = models.CharField(max_length=50) def __iter__(self): for number in xrange(5): yield number def __str__(self): return self.name class ColourfulItem(models.Model): name = models.CharField(max_length=50) colours = models.ManyToManyField(Colour) class ArticleStatusNote(models.Model): name = models.CharField(max_length=20) status = models.ManyToManyField(ArticleStatus) class CustomErrorMessage(models.Model): name1 = models.CharField(max_length=50, validators=[validators.validate_slug], error_messages={'invalid': 'Model custom error message.'}) name2 = models.CharField(max_length=50, validators=[validators.validate_slug], error_messages={'invalid': 'Model custom error message.'}) Django-1.6.11/tests/model_forms/test2.png0000664000175000017500000000403012477341424017634 0ustar timtim00000000000000PNG  IHDR0 ۶lKsRGBbKGD pHYs  tIME-IDATXõWnN"%ʒ,{N $Kȿ9 C^6 쮯E](J}ȹuWadeYk#S]sob;%"| "BT Vm}cbk~t?&1V>f`2O `b`DTB*Tk&"FD)J)%" 7p08QMlVͭf+!(<<;~r|s3[{R(PQxw_N3+)HY6Z XYOɺ_i2R?+/< 3ɫʡB}+!13+)-:JJ%%κYrWieBH`f%>I DQHǴ11bùfhψ532dQJ)h#-1̴%(?J>顨;t;`.f@\N!D%WM.J/29KŬ]ıֈµv-Z1d 2Ą+K@gq]om׫ruӎH)jm`C6ƄQ4x+Ru2 Aqdį~;tuv,RJJDf6dAQġ6Fkmo56ת %7xc? Y ^ D <\vo jrG%Vcg۟~`g^j)LFGgd@KpRZ(WZL@!o6j{OZەb%eo?9zq>0d+;L-Em,iW~^(V ūCoo:R~^MYǐΛFX-;x69?=zd?Fqdt\M[JUV(J!g|M`:yHr``cwy̧ZkT%rJr܏|t00h^3#r\>U7w/?KF;$ژt4.R,ZU&c鈳IENDB`Django-1.6.11/tests/settings_tests/0000775000175000017500000000000012502407547016642 5ustar timtim00000000000000Django-1.6.11/tests/settings_tests/__init__.py0000664000175000017500000000000012477341424020743 0ustar timtim00000000000000Django-1.6.11/tests/settings_tests/tests.py0000664000175000017500000002626312502407523020361 0ustar timtim00000000000000import os import warnings from django.conf import settings, global_settings from django.core.exceptions import ImproperlyConfigured from django.http import HttpRequest from django.test import SimpleTestCase, TransactionTestCase, TestCase, signals from django.test.utils import override_settings from django.utils import unittest, six @override_settings(TEST='override', TEST_OUTER='outer') class FullyDecoratedTranTestCase(TransactionTestCase): available_apps = [] def test_override(self): self.assertEqual(settings.TEST, 'override') self.assertEqual(settings.TEST_OUTER, 'outer') @override_settings(TEST='override2') def test_method_override(self): self.assertEqual(settings.TEST, 'override2') self.assertEqual(settings.TEST_OUTER, 'outer') def test_decorated_testcase_name(self): self.assertEqual(FullyDecoratedTranTestCase.__name__, 'FullyDecoratedTranTestCase') def test_decorated_testcase_module(self): self.assertEqual(FullyDecoratedTranTestCase.__module__, __name__) @override_settings(TEST='override') class FullyDecoratedTestCase(TestCase): def test_override(self): self.assertEqual(settings.TEST, 'override') @override_settings(TEST='override2') def test_method_override(self): self.assertEqual(settings.TEST, 'override2') class ClassDecoratedTestCaseSuper(TestCase): """ Dummy class for testing max recursion error in child class call to super(). Refs #17011. """ def test_max_recursion_error(self): pass @override_settings(TEST='override') class ClassDecoratedTestCase(ClassDecoratedTestCaseSuper): def test_override(self): self.assertEqual(settings.TEST, 'override') @override_settings(TEST='override2') def test_method_override(self): self.assertEqual(settings.TEST, 'override2') def test_max_recursion_error(self): """ Overriding a method on a super class and then calling that method on the super class should not trigger infinite recursion. See #17011. """ try: super(ClassDecoratedTestCase, self).test_max_recursion_error() except RuntimeError: self.fail() class SettingsTests(TestCase): def setUp(self): self.testvalue = None signals.setting_changed.connect(self.signal_callback) def tearDown(self): signals.setting_changed.disconnect(self.signal_callback) def signal_callback(self, sender, setting, value, **kwargs): if setting == 'TEST': self.testvalue = value def test_override(self): settings.TEST = 'test' self.assertEqual('test', settings.TEST) with self.settings(TEST='override'): self.assertEqual('override', settings.TEST) self.assertEqual('test', settings.TEST) del settings.TEST def test_override_change(self): settings.TEST = 'test' self.assertEqual('test', settings.TEST) with self.settings(TEST='override'): self.assertEqual('override', settings.TEST) settings.TEST = 'test2' self.assertEqual('test', settings.TEST) del settings.TEST def test_override_doesnt_leak(self): self.assertRaises(AttributeError, getattr, settings, 'TEST') with self.settings(TEST='override'): self.assertEqual('override', settings.TEST) settings.TEST = 'test' self.assertRaises(AttributeError, getattr, settings, 'TEST') @override_settings(TEST='override') def test_decorator(self): self.assertEqual('override', settings.TEST) def test_context_manager(self): self.assertRaises(AttributeError, getattr, settings, 'TEST') override = override_settings(TEST='override') self.assertRaises(AttributeError, getattr, settings, 'TEST') override.enable() self.assertEqual('override', settings.TEST) override.disable() self.assertRaises(AttributeError, getattr, settings, 'TEST') def test_class_decorator(self): # SimpleTestCase can be decorated by override_settings, but not ut.TestCase class SimpleTestCaseSubclass(SimpleTestCase): pass class UnittestTestCaseSubclass(unittest.TestCase): pass decorated = override_settings(TEST='override')(SimpleTestCaseSubclass) self.assertIsInstance(decorated, type) self.assertTrue(issubclass(decorated, SimpleTestCase)) with six.assertRaisesRegex(self, Exception, "Only subclasses of Django SimpleTestCase*"): decorated = override_settings(TEST='override')(UnittestTestCaseSubclass) def test_signal_callback_context_manager(self): self.assertRaises(AttributeError, getattr, settings, 'TEST') with self.settings(TEST='override'): self.assertEqual(self.testvalue, 'override') self.assertEqual(self.testvalue, None) @override_settings(TEST='override') def test_signal_callback_decorator(self): self.assertEqual(self.testvalue, 'override') # # Regression tests for #10130: deleting settings. # def test_settings_delete(self): settings.TEST = 'test' self.assertEqual('test', settings.TEST) del settings.TEST self.assertRaises(AttributeError, getattr, settings, 'TEST') def test_settings_delete_wrapped(self): self.assertRaises(TypeError, delattr, settings, '_wrapped') def test_override_settings_delete(self): """ Allow deletion of a setting in an overriden settings set (#18824) """ previous_i18n = settings.USE_I18N with self.settings(USE_I18N=False): del settings.USE_I18N self.assertRaises(AttributeError, getattr, settings, 'USE_I18N') self.assertEqual(settings.USE_I18N, previous_i18n) def test_override_settings_nested(self): """ Test that override_settings uses the actual _wrapped attribute at runtime, not when it was instantiated. """ self.assertRaises(AttributeError, getattr, settings, 'TEST') self.assertRaises(AttributeError, getattr, settings, 'TEST2') inner = override_settings(TEST2='override') with override_settings(TEST='override'): self.assertEqual('override', settings.TEST) with inner: self.assertEqual('override', settings.TEST) self.assertEqual('override', settings.TEST2) # inner's __exit__ should have restored the settings of the outer # context manager, not those when the class was instantiated self.assertEqual('override', settings.TEST) self.assertRaises(AttributeError, getattr, settings, 'TEST2') self.assertRaises(AttributeError, getattr, settings, 'TEST') self.assertRaises(AttributeError, getattr, settings, 'TEST2') def test_allowed_include_roots_string(self): """ ALLOWED_INCLUDE_ROOTS is not allowed to be incorrectly set to a string rather than a tuple. """ self.assertRaises(ValueError, setattr, settings, 'ALLOWED_INCLUDE_ROOTS', '/var/www/ssi/') class TrailingSlashURLTests(TestCase): """ Tests for the MEDIA_URL and STATIC_URL settings. They must end with a slash to ensure there's a deterministic way to build paths in templates. """ settings_module = settings def setUp(self): self._original_media_url = self.settings_module.MEDIA_URL self._original_static_url = self.settings_module.STATIC_URL def tearDown(self): self.settings_module.MEDIA_URL = self._original_media_url self.settings_module.STATIC_URL = self._original_static_url def test_blank(self): """ The empty string is accepted, even though it doesn't end in a slash. """ self.settings_module.MEDIA_URL = '' self.assertEqual('', self.settings_module.MEDIA_URL) self.settings_module.STATIC_URL = '' self.assertEqual('', self.settings_module.STATIC_URL) def test_end_slash(self): """ It works if the value ends in a slash. """ self.settings_module.MEDIA_URL = '/foo/' self.assertEqual('/foo/', self.settings_module.MEDIA_URL) self.settings_module.MEDIA_URL = 'http://media.foo.com/' self.assertEqual('http://media.foo.com/', self.settings_module.MEDIA_URL) self.settings_module.STATIC_URL = '/foo/' self.assertEqual('/foo/', self.settings_module.STATIC_URL) self.settings_module.STATIC_URL = 'http://static.foo.com/' self.assertEqual('http://static.foo.com/', self.settings_module.STATIC_URL) def test_no_end_slash(self): """ An ImproperlyConfigured exception is raised if the value doesn't end in a slash. """ with self.assertRaises(ImproperlyConfigured): self.settings_module.MEDIA_URL = '/foo' with self.assertRaises(ImproperlyConfigured): self.settings_module.MEDIA_URL = 'http://media.foo.com' with self.assertRaises(ImproperlyConfigured): self.settings_module.STATIC_URL = '/foo' with self.assertRaises(ImproperlyConfigured): self.settings_module.STATIC_URL = 'http://static.foo.com' def test_double_slash(self): """ If the value ends in more than one slash, presume they know what they're doing. """ self.settings_module.MEDIA_URL = '/stupid//' self.assertEqual('/stupid//', self.settings_module.MEDIA_URL) self.settings_module.MEDIA_URL = 'http://media.foo.com/stupid//' self.assertEqual('http://media.foo.com/stupid//', self.settings_module.MEDIA_URL) self.settings_module.STATIC_URL = '/stupid//' self.assertEqual('/stupid//', self.settings_module.STATIC_URL) self.settings_module.STATIC_URL = 'http://static.foo.com/stupid//' self.assertEqual('http://static.foo.com/stupid//', self.settings_module.STATIC_URL) class SecureProxySslHeaderTest(TestCase): settings_module = settings def setUp(self): self._original_setting = self.settings_module.SECURE_PROXY_SSL_HEADER def tearDown(self): self.settings_module.SECURE_PROXY_SSL_HEADER = self._original_setting def test_none(self): self.settings_module.SECURE_PROXY_SSL_HEADER = None req = HttpRequest() self.assertEqual(req.is_secure(), False) def test_set_without_xheader(self): self.settings_module.SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL', 'https') req = HttpRequest() self.assertEqual(req.is_secure(), False) def test_set_with_xheader_wrong(self): self.settings_module.SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL', 'https') req = HttpRequest() req.META['HTTP_X_FORWARDED_PROTOCOL'] = 'wrongvalue' self.assertEqual(req.is_secure(), False) def test_set_with_xheader_right(self): self.settings_module.SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL', 'https') req = HttpRequest() req.META['HTTP_X_FORWARDED_PROTOCOL'] = 'https' self.assertEqual(req.is_secure(), True) Django-1.6.11/tests/settings_tests/models.py0000664000175000017500000000000012502407523020457 0ustar timtim00000000000000Django-1.6.11/tests/httpwrappers/0000775000175000017500000000000012502407547016323 5ustar timtim00000000000000Django-1.6.11/tests/httpwrappers/abc.txt0000664000175000017500000000001712477341424017611 0ustar timtim00000000000000random content Django-1.6.11/tests/httpwrappers/__init__.py0000664000175000017500000000000012477341424020424 0ustar timtim00000000000000Django-1.6.11/tests/httpwrappers/tests.py0000664000175000017500000006024612502407523020041 0ustar timtim00000000000000# -*- encoding: utf-8 -*- from __future__ import unicode_literals import copy import os import pickle import warnings from django.core.exceptions import SuspiciousOperation from django.core.signals import request_finished from django.db import close_old_connections from django.http import (QueryDict, HttpResponse, HttpResponseRedirect, HttpResponsePermanentRedirect, HttpResponseNotAllowed, HttpResponseNotModified, StreamingHttpResponse, SimpleCookie, BadHeaderError, parse_cookie) from django.test import TestCase from django.utils.encoding import smart_str, force_text from django.utils.functional import lazy from django.utils._os import upath from django.utils import six from django.utils import unittest lazystr = lazy(force_text, six.text_type) class QueryDictTests(unittest.TestCase): def test_missing_key(self): q = QueryDict(str('')) self.assertRaises(KeyError, q.__getitem__, 'foo') def test_immutability(self): q = QueryDict(str('')) self.assertRaises(AttributeError, q.__setitem__, 'something', 'bar') self.assertRaises(AttributeError, q.setlist, 'foo', ['bar']) self.assertRaises(AttributeError, q.appendlist, 'foo', ['bar']) self.assertRaises(AttributeError, q.update, {'foo': 'bar'}) self.assertRaises(AttributeError, q.pop, 'foo') self.assertRaises(AttributeError, q.popitem) self.assertRaises(AttributeError, q.clear) def test_immutable_get_with_default(self): q = QueryDict(str('')) self.assertEqual(q.get('foo', 'default'), 'default') def test_immutable_basic_operations(self): q = QueryDict(str('')) self.assertEqual(q.getlist('foo'), []) if six.PY2: self.assertEqual(q.has_key('foo'), False) self.assertEqual('foo' in q, False) self.assertEqual(list(six.iteritems(q)), []) self.assertEqual(list(six.iterlists(q)), []) self.assertEqual(list(six.iterkeys(q)), []) self.assertEqual(list(six.itervalues(q)), []) self.assertEqual(len(q), 0) self.assertEqual(q.urlencode(), '') def test_single_key_value(self): """Test QueryDict with one key/value pair""" q = QueryDict(str('foo=bar')) self.assertEqual(q['foo'], 'bar') self.assertRaises(KeyError, q.__getitem__, 'bar') self.assertRaises(AttributeError, q.__setitem__, 'something', 'bar') self.assertEqual(q.get('foo', 'default'), 'bar') self.assertEqual(q.get('bar', 'default'), 'default') self.assertEqual(q.getlist('foo'), ['bar']) self.assertEqual(q.getlist('bar'), []) self.assertRaises(AttributeError, q.setlist, 'foo', ['bar']) self.assertRaises(AttributeError, q.appendlist, 'foo', ['bar']) if six.PY2: self.assertTrue(q.has_key('foo')) self.assertTrue('foo' in q) if six.PY2: self.assertFalse(q.has_key('bar')) self.assertFalse('bar' in q) self.assertEqual(list(six.iteritems(q)), [('foo', 'bar')]) self.assertEqual(list(six.iterlists(q)), [('foo', ['bar'])]) self.assertEqual(list(six.iterkeys(q)), ['foo']) self.assertEqual(list(six.itervalues(q)), ['bar']) self.assertEqual(len(q), 1) self.assertRaises(AttributeError, q.update, {'foo': 'bar'}) self.assertRaises(AttributeError, q.pop, 'foo') self.assertRaises(AttributeError, q.popitem) self.assertRaises(AttributeError, q.clear) self.assertRaises(AttributeError, q.setdefault, 'foo', 'bar') self.assertEqual(q.urlencode(), 'foo=bar') def test_urlencode(self): q = QueryDict(str(''), mutable=True) q['next'] = '/a&b/' self.assertEqual(q.urlencode(), 'next=%2Fa%26b%2F') self.assertEqual(q.urlencode(safe='/'), 'next=/a%26b/') q = QueryDict(str(''), mutable=True) q['next'] = '/t\xebst&key/' self.assertEqual(q.urlencode(), 'next=%2Ft%C3%ABst%26key%2F') self.assertEqual(q.urlencode(safe='/'), 'next=/t%C3%ABst%26key/') def test_mutable_copy(self): """A copy of a QueryDict is mutable.""" q = QueryDict(str('')).copy() self.assertRaises(KeyError, q.__getitem__, "foo") q['name'] = 'john' self.assertEqual(q['name'], 'john') def test_mutable_delete(self): q = QueryDict(str('')).copy() q['name'] = 'john' del q['name'] self.assertFalse('name' in q) def test_basic_mutable_operations(self): q = QueryDict(str('')).copy() q['name'] = 'john' self.assertEqual(q.get('foo', 'default'), 'default') self.assertEqual(q.get('name', 'default'), 'john') self.assertEqual(q.getlist('name'), ['john']) self.assertEqual(q.getlist('foo'), []) q.setlist('foo', ['bar', 'baz']) self.assertEqual(q.get('foo', 'default'), 'baz') self.assertEqual(q.getlist('foo'), ['bar', 'baz']) q.appendlist('foo', 'another') self.assertEqual(q.getlist('foo'), ['bar', 'baz', 'another']) self.assertEqual(q['foo'], 'another') if six.PY2: self.assertTrue(q.has_key('foo')) self.assertTrue('foo' in q) self.assertListEqual(sorted(list(six.iteritems(q))), [('foo', 'another'), ('name', 'john')]) self.assertListEqual(sorted(list(six.iterlists(q))), [('foo', ['bar', 'baz', 'another']), ('name', ['john'])]) self.assertListEqual(sorted(list(six.iterkeys(q))), ['foo', 'name']) self.assertListEqual(sorted(list(six.itervalues(q))), ['another', 'john']) q.update({'foo': 'hello'}) self.assertEqual(q['foo'], 'hello') self.assertEqual(q.get('foo', 'not available'), 'hello') self.assertEqual(q.getlist('foo'), ['bar', 'baz', 'another', 'hello']) self.assertEqual(q.pop('foo'), ['bar', 'baz', 'another', 'hello']) self.assertEqual(q.pop('foo', 'not there'), 'not there') self.assertEqual(q.get('foo', 'not there'), 'not there') self.assertEqual(q.setdefault('foo', 'bar'), 'bar') self.assertEqual(q['foo'], 'bar') self.assertEqual(q.getlist('foo'), ['bar']) self.assertIn(q.urlencode(), ['foo=bar&name=john', 'name=john&foo=bar']) q.clear() self.assertEqual(len(q), 0) def test_multiple_keys(self): """Test QueryDict with two key/value pairs with same keys.""" q = QueryDict(str('vote=yes&vote=no')) self.assertEqual(q['vote'], 'no') self.assertRaises(AttributeError, q.__setitem__, 'something', 'bar') self.assertEqual(q.get('vote', 'default'), 'no') self.assertEqual(q.get('foo', 'default'), 'default') self.assertEqual(q.getlist('vote'), ['yes', 'no']) self.assertEqual(q.getlist('foo'), []) self.assertRaises(AttributeError, q.setlist, 'foo', ['bar', 'baz']) self.assertRaises(AttributeError, q.setlist, 'foo', ['bar', 'baz']) self.assertRaises(AttributeError, q.appendlist, 'foo', ['bar']) if six.PY2: self.assertEqual(q.has_key('vote'), True) self.assertEqual('vote' in q, True) if six.PY2: self.assertEqual(q.has_key('foo'), False) self.assertEqual('foo' in q, False) self.assertEqual(list(six.iteritems(q)), [('vote', 'no')]) self.assertEqual(list(six.iterlists(q)), [('vote', ['yes', 'no'])]) self.assertEqual(list(six.iterkeys(q)), ['vote']) self.assertEqual(list(six.itervalues(q)), ['no']) self.assertEqual(len(q), 1) self.assertRaises(AttributeError, q.update, {'foo': 'bar'}) self.assertRaises(AttributeError, q.pop, 'foo') self.assertRaises(AttributeError, q.popitem) self.assertRaises(AttributeError, q.clear) self.assertRaises(AttributeError, q.setdefault, 'foo', 'bar') self.assertRaises(AttributeError, q.__delitem__, 'vote') if six.PY2: def test_invalid_input_encoding(self): """ QueryDicts must be able to handle invalid input encoding (in this case, bad UTF-8 encoding). This test doesn't apply under Python 3 because the URL is a string and not a bytestring. """ q = QueryDict(str(b'foo=bar&foo=\xff')) self.assertEqual(q['foo'], '\ufffd') self.assertEqual(q.getlist('foo'), ['bar', '\ufffd']) def test_pickle(self): q = QueryDict(str('')) q1 = pickle.loads(pickle.dumps(q, 2)) self.assertEqual(q == q1, True) q = QueryDict(str('a=b&c=d')) q1 = pickle.loads(pickle.dumps(q, 2)) self.assertEqual(q == q1, True) q = QueryDict(str('a=b&c=d&a=1')) q1 = pickle.loads(pickle.dumps(q, 2)) self.assertEqual(q == q1, True) def test_update_from_querydict(self): """Regression test for #8278: QueryDict.update(QueryDict)""" x = QueryDict(str("a=1&a=2"), mutable=True) y = QueryDict(str("a=3&a=4")) x.update(y) self.assertEqual(x.getlist('a'), ['1', '2', '3', '4']) def test_non_default_encoding(self): """#13572 - QueryDict with a non-default encoding""" q = QueryDict(str('cur=%A4'), encoding='iso-8859-15') self.assertEqual(q.encoding, 'iso-8859-15') self.assertEqual(list(six.iteritems(q)), [('cur', '€')]) self.assertEqual(q.urlencode(), 'cur=%A4') q = q.copy() self.assertEqual(q.encoding, 'iso-8859-15') self.assertEqual(list(six.iteritems(q)), [('cur', '€')]) self.assertEqual(q.urlencode(), 'cur=%A4') self.assertEqual(copy.copy(q).encoding, 'iso-8859-15') self.assertEqual(copy.deepcopy(q).encoding, 'iso-8859-15') class HttpResponseTests(unittest.TestCase): def test_headers_type(self): r = HttpResponse() # The following tests explicitly test types in addition to values # because in Python 2 u'foo' == b'foo'. # ASCII unicode or bytes values are converted to native strings. r['key'] = 'test' self.assertEqual(r['key'], str('test')) self.assertIsInstance(r['key'], str) r['key'] = 'test'.encode('ascii') self.assertEqual(r['key'], str('test')) self.assertIsInstance(r['key'], str) self.assertIn(b'test', r.serialize_headers()) # Latin-1 unicode or bytes values are also converted to native strings. r['key'] = 'café' self.assertEqual(r['key'], smart_str('café', 'latin-1')) self.assertIsInstance(r['key'], str) r['key'] = 'café'.encode('latin-1') self.assertEqual(r['key'], smart_str('café', 'latin-1')) self.assertIsInstance(r['key'], str) self.assertIn('café'.encode('latin-1'), r.serialize_headers()) # Other unicode values are MIME-encoded (there's no way to pass them as bytes). r['key'] = '†' self.assertEqual(r['key'], str('=?utf-8?b?4oCg?=')) self.assertIsInstance(r['key'], str) self.assertIn(b'=?utf-8?b?4oCg?=', r.serialize_headers()) # The response also converts unicode or bytes keys to strings, but requires # them to contain ASCII r = HttpResponse() del r['Content-Type'] r['foo'] = 'bar' l = list(r.items()) self.assertEqual(len(l), 1) self.assertEqual(l[0], ('foo', 'bar')) self.assertIsInstance(l[0][0], str) r = HttpResponse() del r['Content-Type'] r[b'foo'] = 'bar' l = list(r.items()) self.assertEqual(len(l), 1) self.assertEqual(l[0], ('foo', 'bar')) self.assertIsInstance(l[0][0], str) r = HttpResponse() self.assertRaises(UnicodeError, r.__setitem__, 'føø', 'bar') self.assertRaises(UnicodeError, r.__setitem__, 'føø'.encode('utf-8'), 'bar') def test_newlines_in_headers(self): # Bug #10188: Do not allow newlines in headers (CR or LF) r = HttpResponse() self.assertRaises(BadHeaderError, r.__setitem__, 'test\rstr', 'test') self.assertRaises(BadHeaderError, r.__setitem__, 'test\nstr', 'test') def test_dict_behavior(self): """ Test for bug #14020: Make HttpResponse.get work like dict.get """ r = HttpResponse() self.assertEqual(r.get('test'), None) def test_non_string_content(self): #Bug 16494: HttpResponse should behave consistently with non-strings r = HttpResponse(12345) self.assertEqual(r.content, b'12345') #test content via property r = HttpResponse() r.content = 12345 self.assertEqual(r.content, b'12345') def test_iter_content(self): r = HttpResponse(['abc', 'def', 'ghi']) self.assertEqual(r.content, b'abcdefghi') #test iter content via property r = HttpResponse() r.content = ['idan', 'alex', 'jacob'] self.assertEqual(r.content, b'idanalexjacob') r = HttpResponse() r.content = [1, 2, 3] self.assertEqual(r.content, b'123') #test retrieval explicitly using iter (deprecated) and odd inputs r = HttpResponse() r.content = ['1', '2', 3, '\u079e'] with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always", DeprecationWarning) my_iter = iter(r) self.assertEqual(w[0].category, DeprecationWarning) with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always", DeprecationWarning) result = list(my_iter) self.assertEqual(w[0].category, DeprecationWarning) #'\xde\x9e' == unichr(1950).encode('utf-8') self.assertEqual(result, [b'1', b'2', b'3', b'\xde\x9e']) self.assertEqual(r.content, b'123\xde\x9e') #with Content-Encoding header r = HttpResponse() r['Content-Encoding'] = 'winning' r.content = [b'abc', b'def'] self.assertEqual(r.content, b'abcdef') r.content = ['\u079e'] self.assertRaises(TypeError if six.PY3 else UnicodeEncodeError, getattr, r, 'content') # .content can safely be accessed multiple times. r = HttpResponse(iter(['hello', 'world'])) self.assertEqual(r.content, r.content) self.assertEqual(r.content, b'helloworld') # accessing the iterator works (once) after accessing .content self.assertEqual(b''.join(r), b'helloworld') self.assertEqual(b''.join(r), b'') # accessing .content still works self.assertEqual(r.content, b'helloworld') # XXX accessing .content doesn't work if the response was iterated first # XXX change this when the deprecation completes in HttpResponse r = HttpResponse(iter(['hello', 'world'])) with warnings.catch_warnings(): warnings.simplefilter("ignore", DeprecationWarning) self.assertEqual(b''.join(r), b'helloworld') self.assertEqual(r.content, b'') # not the expected result! # additional content can be written to the response. r = HttpResponse(iter(['hello', 'world'])) self.assertEqual(r.content, b'helloworld') r.write('!') self.assertEqual(r.content, b'helloworld!') def test_iterator_isnt_rewound(self): # Regression test for #13222 r = HttpResponse('abc') i = iter(r) self.assertEqual(list(i), [b'abc']) self.assertEqual(list(i), []) def test_lazy_content(self): r = HttpResponse(lazystr('helloworld')) self.assertEqual(r.content, b'helloworld') def test_file_interface(self): r = HttpResponse() r.write(b"hello") self.assertEqual(r.tell(), 5) r.write("привет") self.assertEqual(r.tell(), 17) r = HttpResponse(['abc']) r.write('def') self.assertEqual(r.tell(), 6) self.assertEqual(r.content, b'abcdef') # with Content-Encoding header r = HttpResponse() r['Content-Encoding'] = 'winning' r.write(b'abc') r.write(b'def') self.assertEqual(r.content, b'abcdef') def test_unsafe_redirect(self): bad_urls = [ 'data:text/html,', 'mailto:test@example.com', 'file:///etc/passwd', ] for url in bad_urls: self.assertRaises(SuspiciousOperation, HttpResponseRedirect, url) self.assertRaises(SuspiciousOperation, HttpResponsePermanentRedirect, url) class HttpResponseSubclassesTests(TestCase): def test_redirect(self): response = HttpResponseRedirect('/redirected/') self.assertEqual(response.status_code, 302) # Test that standard HttpResponse init args can be used response = HttpResponseRedirect('/redirected/', content='The resource has temporarily moved', content_type='text/html') self.assertContains(response, 'The resource has temporarily moved', status_code=302) # Test that url attribute is right self.assertEqual(response.url, response['Location']) def test_redirect_lazy(self): """Make sure HttpResponseRedirect works with lazy strings.""" r = HttpResponseRedirect(lazystr('/redirected/')) self.assertEqual(r.url, '/redirected/') def test_not_modified(self): response = HttpResponseNotModified() self.assertEqual(response.status_code, 304) # 304 responses should not have content/content-type with self.assertRaises(AttributeError): response.content = "Hello dear" self.assertNotIn('content-type', response) def test_not_allowed(self): response = HttpResponseNotAllowed(['GET']) self.assertEqual(response.status_code, 405) # Test that standard HttpResponse init args can be used response = HttpResponseNotAllowed(['GET'], content='Only the GET method is allowed', content_type='text/html') self.assertContains(response, 'Only the GET method is allowed', status_code=405) class StreamingHttpResponseTests(TestCase): def test_streaming_response(self): r = StreamingHttpResponse(iter(['hello', 'world'])) # iterating over the response itself yields bytestring chunks. chunks = list(r) self.assertEqual(chunks, [b'hello', b'world']) for chunk in chunks: self.assertIsInstance(chunk, six.binary_type) # and the response can only be iterated once. self.assertEqual(list(r), []) # even when a sequence that can be iterated many times, like a list, # is given as content. r = StreamingHttpResponse(['abc', 'def']) self.assertEqual(list(r), [b'abc', b'def']) self.assertEqual(list(r), []) # streaming responses don't have a `content` attribute. self.assertFalse(hasattr(r, 'content')) # and you can't accidentally assign to a `content` attribute. with self.assertRaises(AttributeError): r.content = 'xyz' # but they do have a `streaming_content` attribute. self.assertTrue(hasattr(r, 'streaming_content')) # that exists so we can check if a response is streaming, and wrap or # replace the content iterator. r.streaming_content = iter(['abc', 'def']) r.streaming_content = (chunk.upper() for chunk in r.streaming_content) self.assertEqual(list(r), [b'ABC', b'DEF']) # coercing a streaming response to bytes doesn't return a complete HTTP # message like a regular response does. it only gives us the headers. r = StreamingHttpResponse(iter(['hello', 'world'])) self.assertEqual( six.binary_type(r), b'Content-Type: text/html; charset=utf-8') # and this won't consume its content. self.assertEqual(list(r), [b'hello', b'world']) # additional content cannot be written to the response. r = StreamingHttpResponse(iter(['hello', 'world'])) with self.assertRaises(Exception): r.write('!') # and we can't tell the current position. with self.assertRaises(Exception): r.tell() class FileCloseTests(TestCase): def setUp(self): # Disable the request_finished signal during this test # to avoid interfering with the database connection. request_finished.disconnect(close_old_connections) def tearDown(self): request_finished.connect(close_old_connections) def test_response(self): filename = os.path.join(os.path.dirname(upath(__file__)), 'abc.txt') # file isn't closed until we close the response. file1 = open(filename) r = HttpResponse(file1) self.assertFalse(file1.closed) r.close() self.assertTrue(file1.closed) # don't automatically close file when we finish iterating the response. file1 = open(filename) r = HttpResponse(file1) self.assertFalse(file1.closed) with warnings.catch_warnings(): warnings.simplefilter("ignore", DeprecationWarning) list(r) self.assertFalse(file1.closed) r.close() self.assertTrue(file1.closed) # when multiple file are assigned as content, make sure they are all # closed with the response. file1 = open(filename) file2 = open(filename) r = HttpResponse(file1) r.content = file2 self.assertFalse(file1.closed) self.assertFalse(file2.closed) r.close() self.assertTrue(file1.closed) self.assertTrue(file2.closed) def test_streaming_response(self): filename = os.path.join(os.path.dirname(upath(__file__)), 'abc.txt') # file isn't closed until we close the response. file1 = open(filename) r = StreamingHttpResponse(file1) self.assertFalse(file1.closed) r.close() self.assertTrue(file1.closed) # when multiple file are assigned as content, make sure they are all # closed with the response. file1 = open(filename) file2 = open(filename) r = StreamingHttpResponse(file1) r.streaming_content = file2 self.assertFalse(file1.closed) self.assertFalse(file2.closed) r.close() self.assertTrue(file1.closed) self.assertTrue(file2.closed) class CookieTests(unittest.TestCase): def test_encode(self): """ Test that we don't output tricky characters in encoded value """ c = SimpleCookie() c['test'] = "An,awkward;value" self.assertTrue(";" not in c.output().rstrip(';')) # IE compat self.assertTrue("," not in c.output().rstrip(';')) # Safari compat def test_decode(self): """ Test that we can still preserve semi-colons and commas """ c = SimpleCookie() c['test'] = "An,awkward;value" c2 = SimpleCookie() c2.load(c.output()) self.assertEqual(c['test'].value, c2['test'].value) def test_decode_2(self): """ Test that we haven't broken normal encoding """ c = SimpleCookie() c['test'] = b"\xf0" c2 = SimpleCookie() c2.load(c.output()) self.assertEqual(c['test'].value, c2['test'].value) def test_nonstandard_keys(self): """ Test that a single non-standard cookie name doesn't affect all cookies. Ticket #13007. """ self.assertTrue('good_cookie' in parse_cookie('good_cookie=yes;bad:cookie=yes').keys()) def test_repeated_nonstandard_keys(self): """ Test that a repeated non-standard name doesn't affect all cookies. Ticket #15852 """ self.assertTrue('good_cookie' in parse_cookie('a:=b; a:=c; good_cookie=yes').keys()) def test_httponly_after_load(self): """ Test that we can use httponly attribute on cookies that we load """ c = SimpleCookie() c.load("name=val") c['name']['httponly'] = True self.assertTrue(c['name']['httponly']) def test_load_dict(self): c = SimpleCookie() c.load({'name': 'val'}) self.assertEqual(c['name'].value, 'val') Django-1.6.11/tests/httpwrappers/models.py0000664000175000017500000000000012502407523020140 0ustar timtim00000000000000Django-1.6.11/tests/version/0000775000175000017500000000000012502407547015245 5ustar timtim00000000000000Django-1.6.11/tests/version/__init__.py0000664000175000017500000000000012477341424017346 0ustar timtim00000000000000Django-1.6.11/tests/version/tests.py0000664000175000017500000000163112502407523016754 0ustar timtim00000000000000import re from django import get_version from django.utils import six from django.utils.unittest import TestCase class VersionTests(TestCase): def test_development(self): ver_tuple = (1, 4, 0, 'alpha', 0) # This will return a different result when it's run within or outside # of a git clone: 1.4.devYYYYMMDDHHMMSS or 1.4. ver_string = get_version(ver_tuple) six.assertRegex(self, ver_string, r'1\.4(\.dev\d+)?') def test_releases(self): tuples_to_strings = ( ((1, 4, 0, 'alpha', 1), '1.4a1'), ((1, 4, 0, 'beta', 1), '1.4b1'), ((1, 4, 0, 'rc', 1), '1.4c1'), ((1, 4, 0, 'final', 0), '1.4'), ((1, 4, 1, 'rc', 2), '1.4.1c2'), ((1, 4, 1, 'final', 0), '1.4.1'), ) for ver_tuple, ver_string in tuples_to_strings: self.assertEqual(get_version(ver_tuple), ver_string) Django-1.6.11/tests/version/models.py0000664000175000017500000000000012502407523017062 0ustar timtim00000000000000Django-1.6.11/tests/m2m_through/0000775000175000017500000000000012502407547016013 5ustar timtim00000000000000Django-1.6.11/tests/m2m_through/__init__.py0000664000175000017500000000000212502407523020106 0ustar timtim00000000000000 Django-1.6.11/tests/m2m_through/tests.py0000664000175000017500000003115412502407523017525 0ustar timtim00000000000000from __future__ import absolute_import from datetime import datetime from operator import attrgetter from django.test import TestCase from .models import (Person, Group, Membership, CustomMembership, PersonSelfRefM2M, Friendship) class M2mThroughTests(TestCase): def setUp(self): self.bob = Person.objects.create(name='Bob') self.jim = Person.objects.create(name='Jim') self.jane = Person.objects.create(name='Jane') self.rock = Group.objects.create(name='Rock') self.roll = Group.objects.create(name='Roll') def test_m2m_through(self): # We start out by making sure that the Group 'rock' has no members. self.assertQuerysetEqual( self.rock.members.all(), [] ) # To make Jim a member of Group Rock, simply create a Membership object. m1 = Membership.objects.create(person=self.jim, group=self.rock) # We can do the same for Jane and Rock. m2 = Membership.objects.create(person=self.jane, group=self.rock) # Let's check to make sure that it worked. Jane and Jim should be members of Rock. self.assertQuerysetEqual( self.rock.members.all(), [ 'Jane', 'Jim' ], attrgetter("name") ) # Now we can add a bunch more Membership objects to test with. m3 = Membership.objects.create(person=self.bob, group=self.roll) m4 = Membership.objects.create(person=self.jim, group=self.roll) m5 = Membership.objects.create(person=self.jane, group=self.roll) # We can get Jim's Group membership as with any ForeignKey. self.assertQuerysetEqual( self.jim.group_set.all(), [ 'Rock', 'Roll' ], attrgetter("name") ) # Querying the intermediary model works like normal. self.assertEqual( repr(Membership.objects.get(person=self.jane, group=self.rock)), '' ) # It's not only get that works. Filter works like normal as well. self.assertQuerysetEqual( Membership.objects.filter(person=self.jim), [ '', '' ] ) self.rock.members.clear() # Now there will be no members of Rock. self.assertQuerysetEqual( self.rock.members.all(), [] ) def test_forward_descriptors(self): # Due to complications with adding via an intermediary model, # the add method is not provided. self.assertRaises(AttributeError, lambda: self.rock.members.add(self.bob)) # Create is also disabled as it suffers from the same problems as add. self.assertRaises(AttributeError, lambda: self.rock.members.create(name='Anne')) # Remove has similar complications, and is not provided either. self.assertRaises(AttributeError, lambda: self.rock.members.remove(self.jim)) m1 = Membership.objects.create(person=self.jim, group=self.rock) m2 = Membership.objects.create(person=self.jane, group=self.rock) # Here we back up the list of all members of Rock. backup = list(self.rock.members.all()) # ...and we verify that it has worked. self.assertEqual( [p.name for p in backup], ['Jane', 'Jim'] ) # The clear function should still work. self.rock.members.clear() # Now there will be no members of Rock. self.assertQuerysetEqual( self.rock.members.all(), [] ) # Assignment should not work with models specifying a through model for many of # the same reasons as adding. self.assertRaises(AttributeError, setattr, self.rock, "members", backup) # Let's re-save those instances that we've cleared. m1.save() m2.save() # Verifying that those instances were re-saved successfully. self.assertQuerysetEqual( self.rock.members.all(),[ 'Jane', 'Jim' ], attrgetter("name") ) def test_reverse_descriptors(self): # Due to complications with adding via an intermediary model, # the add method is not provided. self.assertRaises(AttributeError, lambda: self.bob.group_set.add(self.rock)) # Create is also disabled as it suffers from the same problems as add. self.assertRaises(AttributeError, lambda: self.bob.group_set.create(name="funk")) # Remove has similar complications, and is not provided either. self.assertRaises(AttributeError, lambda: self.jim.group_set.remove(self.rock)) m1 = Membership.objects.create(person=self.jim, group=self.rock) m2 = Membership.objects.create(person=self.jim, group=self.roll) # Here we back up the list of all of Jim's groups. backup = list(self.jim.group_set.all()) self.assertEqual( [g.name for g in backup], ['Rock', 'Roll'] ) # The clear function should still work. self.jim.group_set.clear() # Now Jim will be in no groups. self.assertQuerysetEqual( self.jim.group_set.all(), [] ) # Assignment should not work with models specifying a through model for many of # the same reasons as adding. self.assertRaises(AttributeError, setattr, self.jim, "group_set", backup) # Let's re-save those instances that we've cleared. m1.save() m2.save() # Verifying that those instances were re-saved successfully. self.assertQuerysetEqual( self.jim.group_set.all(),[ 'Rock', 'Roll' ], attrgetter("name") ) def test_custom_tests(self): # Let's see if we can query through our second relationship. self.assertQuerysetEqual( self.rock.custom_members.all(), [] ) # We can query in the opposite direction as well. self.assertQuerysetEqual( self.bob.custom.all(), [] ) cm1 = CustomMembership.objects.create(person=self.bob, group=self.rock) cm2 = CustomMembership.objects.create(person=self.jim, group=self.rock) # If we get the number of people in Rock, it should be both Bob and Jim. self.assertQuerysetEqual( self.rock.custom_members.all(),[ 'Bob', 'Jim' ], attrgetter("name") ) # Bob should only be in one custom group. self.assertQuerysetEqual( self.bob.custom.all(),[ 'Rock' ], attrgetter("name") ) # Let's make sure our new descriptors don't conflict with the FK related_name. self.assertQuerysetEqual( self.bob.custom_person_related_name.all(),[ '' ] ) def test_self_referential_tests(self): # Let's first create a person who has no friends. tony = PersonSelfRefM2M.objects.create(name="Tony") self.assertQuerysetEqual( tony.friends.all(), [] ) chris = PersonSelfRefM2M.objects.create(name="Chris") f = Friendship.objects.create(first=tony, second=chris, date_friended=datetime.now()) # Tony should now show that Chris is his friend. self.assertQuerysetEqual( tony.friends.all(),[ 'Chris' ], attrgetter("name") ) # But we haven't established that Chris is Tony's Friend. self.assertQuerysetEqual( chris.friends.all(), [] ) f2 = Friendship.objects.create(first=chris, second=tony, date_friended=datetime.now()) # Having added Chris as a friend, let's make sure that his friend set reflects # that addition. self.assertQuerysetEqual( chris.friends.all(),[ 'Tony' ], attrgetter("name") ) # Chris gets mad and wants to get rid of all of his friends. chris.friends.clear() # Now he should not have any more friends. self.assertQuerysetEqual( chris.friends.all(), [] ) # Since this isn't a symmetrical relation, Tony's friend link still exists. self.assertQuerysetEqual( tony.friends.all(),[ 'Chris' ], attrgetter("name") ) def test_query_tests(self): m1 = Membership.objects.create(person=self.jim, group=self.rock) m2 = Membership.objects.create(person=self.jane, group=self.rock) m3 = Membership.objects.create(person=self.bob, group=self.roll) m4 = Membership.objects.create(person=self.jim, group=self.roll) m5 = Membership.objects.create(person=self.jane, group=self.roll) m2.invite_reason = "She was just awesome." m2.date_joined = datetime(2006, 1, 1) m2.save() m3.date_joined = datetime(2004, 1, 1) m3.save() m5.date_joined = datetime(2004, 1, 1) m5.save() # We can query for the related model by using its attribute name (members, in # this case). self.assertQuerysetEqual( Group.objects.filter(members__name='Bob'),[ 'Roll' ], attrgetter("name") ) # To query through the intermediary model, we specify its model name. # In this case, membership. self.assertQuerysetEqual( Group.objects.filter(membership__invite_reason="She was just awesome."),[ 'Rock' ], attrgetter("name") ) # If we want to query in the reverse direction by the related model, use its # model name (group, in this case). self.assertQuerysetEqual( Person.objects.filter(group__name="Rock"),[ 'Jane', 'Jim' ], attrgetter("name") ) cm1 = CustomMembership.objects.create(person=self.bob, group=self.rock) cm2 = CustomMembership.objects.create(person=self.jim, group=self.rock) # If the m2m field has specified a related_name, using that will work. self.assertQuerysetEqual( Person.objects.filter(custom__name="Rock"),[ 'Bob', 'Jim' ], attrgetter("name") ) # To query through the intermediary model in the reverse direction, we again # specify its model name (membership, in this case). self.assertQuerysetEqual( Person.objects.filter(membership__invite_reason="She was just awesome."),[ 'Jane' ], attrgetter("name") ) # Let's see all of the groups that Jane joined after 1 Jan 2005: self.assertQuerysetEqual( Group.objects.filter(membership__date_joined__gt=datetime(2005, 1, 1), membership__person=self.jane),[ 'Rock' ], attrgetter("name") ) # Queries also work in the reverse direction: Now let's see all of the people # that have joined Rock since 1 Jan 2005: self.assertQuerysetEqual( Person.objects.filter(membership__date_joined__gt=datetime(2005, 1, 1), membership__group=self.rock),[ 'Jane', 'Jim' ], attrgetter("name") ) # Conceivably, queries through membership could return correct, but non-unique # querysets. To demonstrate this, we query for all people who have joined a # group after 2004: self.assertQuerysetEqual( Person.objects.filter(membership__date_joined__gt=datetime(2004, 1, 1)),[ 'Jane', 'Jim', 'Jim' ], attrgetter("name") ) # Jim showed up twice, because he joined two groups ('Rock', and 'Roll'): self.assertEqual( [(m.person.name, m.group.name) for m in Membership.objects.filter(date_joined__gt=datetime(2004, 1, 1))], [('Jane', 'Rock'), ('Jim', 'Rock'), ('Jim', 'Roll')] ) # QuerySet's distinct() method can correct this problem. self.assertQuerysetEqual( Person.objects.filter(membership__date_joined__gt=datetime(2004, 1, 1)).distinct(),[ 'Jane', 'Jim' ], attrgetter("name") ) Django-1.6.11/tests/m2m_through/models.py0000664000175000017500000000456712502407523017656 0ustar timtim00000000000000from datetime import datetime from django.db import models from django.utils.encoding import python_2_unicode_compatible # M2M described on one of the models @python_2_unicode_compatible class Person(models.Model): name = models.CharField(max_length=128) class Meta: ordering = ('name',) def __str__(self): return self.name @python_2_unicode_compatible class Group(models.Model): name = models.CharField(max_length=128) members = models.ManyToManyField(Person, through='Membership') custom_members = models.ManyToManyField(Person, through='CustomMembership', related_name="custom") nodefaultsnonulls = models.ManyToManyField(Person, through='TestNoDefaultsOrNulls', related_name="testnodefaultsnonulls") class Meta: ordering = ('name',) def __str__(self): return self.name @python_2_unicode_compatible class Membership(models.Model): person = models.ForeignKey(Person) group = models.ForeignKey(Group) date_joined = models.DateTimeField(default=datetime.now) invite_reason = models.CharField(max_length=64, null=True) class Meta: ordering = ('date_joined', 'invite_reason', 'group') def __str__(self): return "%s is a member of %s" % (self.person.name, self.group.name) @python_2_unicode_compatible class CustomMembership(models.Model): person = models.ForeignKey(Person, db_column="custom_person_column", related_name="custom_person_related_name") group = models.ForeignKey(Group) weird_fk = models.ForeignKey(Membership, null=True) date_joined = models.DateTimeField(default=datetime.now) def __str__(self): return "%s is a member of %s" % (self.person.name, self.group.name) class Meta: db_table = "test_table" class TestNoDefaultsOrNulls(models.Model): person = models.ForeignKey(Person) group = models.ForeignKey(Group) nodefaultnonull = models.CharField(max_length=5) @python_2_unicode_compatible class PersonSelfRefM2M(models.Model): name = models.CharField(max_length=5) friends = models.ManyToManyField('self', through="Friendship", symmetrical=False) def __str__(self): return self.name class Friendship(models.Model): first = models.ForeignKey(PersonSelfRefM2M, related_name="rel_from_set") second = models.ForeignKey(PersonSelfRefM2M, related_name="rel_to_set") date_friended = models.DateTimeField() Django-1.6.11/tests/http_utils/0000775000175000017500000000000012502407547015757 5ustar timtim00000000000000Django-1.6.11/tests/http_utils/__init__.py0000664000175000017500000000000012477341424020060 0ustar timtim00000000000000Django-1.6.11/tests/http_utils/tests.py0000664000175000017500000000427612502407523017476 0ustar timtim00000000000000from __future__ import unicode_literals import io import gzip from django.http import HttpRequest, HttpResponse, StreamingHttpResponse from django.http.utils import conditional_content_removal from django.test import TestCase # based on Python 3.3's gzip.compress def gzip_compress(data): buf = io.BytesIO() f = gzip.GzipFile(fileobj=buf, mode='wb', compresslevel=0) try: f.write(data) finally: f.close() return buf.getvalue() class HttpUtilTests(TestCase): def test_conditional_content_removal(self): """ Tests that content is removed from regular and streaming responses with a status_code of 100-199, 204, 304 or a method of "HEAD". """ req = HttpRequest() # Do nothing for 200 responses. res = HttpResponse('abc') conditional_content_removal(req, res) self.assertEqual(res.content, b'abc') res = StreamingHttpResponse(['abc']) conditional_content_removal(req, res) self.assertEqual(b''.join(res), b'abc') # Strip content for some status codes. for status_code in (100, 150, 199, 204, 304): res = HttpResponse('abc', status=status_code) conditional_content_removal(req, res) self.assertEqual(res.content, b'') res = StreamingHttpResponse(['abc'], status=status_code) conditional_content_removal(req, res) self.assertEqual(b''.join(res), b'') # Issue #20472 abc = gzip_compress(b'abc') res = HttpResponse(abc, status=304) res['Content-Encoding'] = 'gzip' conditional_content_removal(req, res) self.assertEqual(res.content, b'') res = StreamingHttpResponse([abc], status=304) res['Content-Encoding'] = 'gzip' conditional_content_removal(req, res) self.assertEqual(b''.join(res), b'') # Strip content for HEAD requests. req.method = 'HEAD' res = HttpResponse('abc') conditional_content_removal(req, res) self.assertEqual(res.content, b'') res = StreamingHttpResponse(['abc']) conditional_content_removal(req, res) self.assertEqual(b''.join(res), b'') Django-1.6.11/tests/http_utils/models.py0000664000175000017500000000000012502407523017574 0ustar timtim00000000000000Django-1.6.11/tests/save_delete_hooks/0000775000175000017500000000000012502407547017243 5ustar timtim00000000000000Django-1.6.11/tests/save_delete_hooks/__init__.py0000664000175000017500000000000012477341424021344 0ustar timtim00000000000000Django-1.6.11/tests/save_delete_hooks/tests.py0000664000175000017500000000143412502407523020753 0ustar timtim00000000000000from __future__ import absolute_import from django.test import TestCase from django.utils import six from .models import Person class SaveDeleteHookTests(TestCase): def test_basic(self): p = Person(first_name="John", last_name="Smith") self.assertEqual(p.data, []) p.save() self.assertEqual(p.data, [ "Before save", "After save", ]) self.assertQuerysetEqual( Person.objects.all(), [ "John Smith", ], six.text_type ) p.delete() self.assertEqual(p.data, [ "Before save", "After save", "Before deletion", "After deletion", ]) self.assertQuerysetEqual(Person.objects.all(), []) Django-1.6.11/tests/save_delete_hooks/models.py0000664000175000017500000000201312502407523021066 0ustar timtim00000000000000""" 13. Adding hooks before/after saving and deleting To execute arbitrary code around ``save()`` and ``delete()``, just subclass the methods. """ from __future__ import unicode_literals from django.db import models from django.utils.encoding import python_2_unicode_compatible @python_2_unicode_compatible class Person(models.Model): first_name = models.CharField(max_length=20) last_name = models.CharField(max_length=20) def __init__(self, *args, **kwargs): super(Person, self).__init__(*args, **kwargs) self.data = [] def __str__(self): return "%s %s" % (self.first_name, self.last_name) def save(self, *args, **kwargs): self.data.append("Before save") # Call the "real" save() method super(Person, self).save(*args, **kwargs) self.data.append("After save") def delete(self): self.data.append("Before deletion") # Call the "real" delete() method super(Person, self).delete() self.data.append("After deletion") Django-1.6.11/tests/inline_formsets/0000775000175000017500000000000012502407547016760 5ustar timtim00000000000000Django-1.6.11/tests/inline_formsets/__init__.py0000664000175000017500000000000012477341424021061 0ustar timtim00000000000000Django-1.6.11/tests/inline_formsets/tests.py0000664000175000017500000001502012502407523020464 0ustar timtim00000000000000from __future__ import absolute_import, unicode_literals from django.forms.models import inlineformset_factory from django.test import TestCase, skipUnlessDBFeature from django.utils import six from .models import Poet, Poem, School, Parent, Child class DeletionTests(TestCase): def test_deletion(self): PoemFormSet = inlineformset_factory(Poet, Poem, can_delete=True, fields="__all__") poet = Poet.objects.create(name='test') poem = poet.poem_set.create(name='test poem') data = { 'poem_set-TOTAL_FORMS': '1', 'poem_set-INITIAL_FORMS': '1', 'poem_set-MAX_NUM_FORMS': '0', 'poem_set-0-id': str(poem.pk), 'poem_set-0-poet': str(poet.pk), 'poem_set-0-name': 'test', 'poem_set-0-DELETE': 'on', } formset = PoemFormSet(data, instance=poet) formset.save() self.assertTrue(formset.is_valid()) self.assertEqual(Poem.objects.count(), 0) def test_add_form_deletion_when_invalid(self): """ Make sure that an add form that is filled out, but marked for deletion doesn't cause validation errors. """ PoemFormSet = inlineformset_factory(Poet, Poem, can_delete=True, fields="__all__") poet = Poet.objects.create(name='test') data = { 'poem_set-TOTAL_FORMS': '1', 'poem_set-INITIAL_FORMS': '0', 'poem_set-MAX_NUM_FORMS': '0', 'poem_set-0-id': '', 'poem_set-0-poem': '1', 'poem_set-0-name': 'x' * 1000, } formset = PoemFormSet(data, instance=poet) # Make sure this form doesn't pass validation. self.assertEqual(formset.is_valid(), False) self.assertEqual(Poem.objects.count(), 0) # Then make sure that it *does* pass validation and delete the object, # even though the data isn't actually valid. data['poem_set-0-DELETE'] = 'on' formset = PoemFormSet(data, instance=poet) self.assertEqual(formset.is_valid(), True) formset.save() self.assertEqual(Poem.objects.count(), 0) def test_change_form_deletion_when_invalid(self): """ Make sure that a change form that is filled out, but marked for deletion doesn't cause validation errors. """ PoemFormSet = inlineformset_factory(Poet, Poem, can_delete=True, fields="__all__") poet = Poet.objects.create(name='test') poem = poet.poem_set.create(name='test poem') data = { 'poem_set-TOTAL_FORMS': '1', 'poem_set-INITIAL_FORMS': '1', 'poem_set-MAX_NUM_FORMS': '0', 'poem_set-0-id': six.text_type(poem.id), 'poem_set-0-poem': six.text_type(poem.id), 'poem_set-0-name': 'x' * 1000, } formset = PoemFormSet(data, instance=poet) # Make sure this form doesn't pass validation. self.assertEqual(formset.is_valid(), False) self.assertEqual(Poem.objects.count(), 1) # Then make sure that it *does* pass validation and delete the object, # even though the data isn't actually valid. data['poem_set-0-DELETE'] = 'on' formset = PoemFormSet(data, instance=poet) self.assertEqual(formset.is_valid(), True) formset.save() self.assertEqual(Poem.objects.count(), 0) def test_save_new(self): """ Make sure inlineformsets respect commit=False regression for #10750 """ # exclude some required field from the forms ChildFormSet = inlineformset_factory(School, Child, exclude=['father', 'mother']) school = School.objects.create(name='test') mother = Parent.objects.create(name='mother') father = Parent.objects.create(name='father') data = { 'child_set-TOTAL_FORMS': '1', 'child_set-INITIAL_FORMS': '0', 'child_set-MAX_NUM_FORMS': '0', 'child_set-0-name': 'child', } formset = ChildFormSet(data, instance=school) self.assertEqual(formset.is_valid(), True) objects = formset.save(commit=False) for obj in objects: obj.mother = mother obj.father = father obj.save() self.assertEqual(school.child_set.count(), 1) class InlineFormsetFactoryTest(TestCase): def test_inline_formset_factory(self): """ These should both work without a problem. """ inlineformset_factory(Parent, Child, fk_name='mother', fields="__all__") inlineformset_factory(Parent, Child, fk_name='father', fields="__all__") def test_exception_on_unspecified_foreign_key(self): """ Child has two ForeignKeys to Parent, so if we don't specify which one to use for the inline formset, we should get an exception. """ six.assertRaisesRegex(self, Exception, " has more than 1 ForeignKey to ", inlineformset_factory, Parent, Child ) def test_fk_name_not_foreign_key_field_from_child(self): """ If we specify fk_name, but it isn't a ForeignKey from the child model to the parent model, we should get an exception. """ self.assertRaises(Exception, "fk_name 'school' is not a ForeignKey to ", inlineformset_factory, Parent, Child, fk_name='school' ) def test_non_foreign_key_field(self): """ If the field specified in fk_name is not a ForeignKey, we should get an exception. """ six.assertRaisesRegex(self, Exception, " has no field named 'test'", inlineformset_factory, Parent, Child, fk_name='test' ) def test_any_iterable_allowed_as_argument_to_exclude(self): # Regression test for #9171. inlineformset_factory( Parent, Child, exclude=['school'], fk_name='mother' ) inlineformset_factory( Parent, Child, exclude=('school',), fk_name='mother' ) @skipUnlessDBFeature('allows_primary_key_0') def test_zero_primary_key(self): # Regression test for #21472 poet = Poet.objects.create(id=0, name='test') poem = poet.poem_set.create(name='test poem') PoemFormSet = inlineformset_factory(Poet, Poem, fields="__all__", extra=0) formset = PoemFormSet(None, instance=poet) self.assertEqual(len(formset.forms), 1) Django-1.6.11/tests/inline_formsets/models.py0000664000175000017500000000151212502407523020606 0ustar timtim00000000000000# coding: utf-8 from django.db import models from django.utils.encoding import python_2_unicode_compatible class School(models.Model): name = models.CharField(max_length=100) class Parent(models.Model): name = models.CharField(max_length=100) class Child(models.Model): mother = models.ForeignKey(Parent, related_name='mothers_children') father = models.ForeignKey(Parent, related_name='fathers_children') school = models.ForeignKey(School) name = models.CharField(max_length=100) @python_2_unicode_compatible class Poet(models.Model): name = models.CharField(max_length=100) def __str__(self): return self.name @python_2_unicode_compatible class Poem(models.Model): poet = models.ForeignKey(Poet) name = models.CharField(max_length=100) def __str__(self): return self.name Django-1.6.11/tests/select_related_regress/0000775000175000017500000000000012502407547020271 5ustar timtim00000000000000Django-1.6.11/tests/select_related_regress/__init__.py0000664000175000017500000000000012477341424022372 0ustar timtim00000000000000Django-1.6.11/tests/select_related_regress/tests.py0000664000175000017500000002056312502407523022005 0ustar timtim00000000000000from __future__ import absolute_import, unicode_literals from django.test import TestCase from django.utils import six from .models import (Building, Child, Device, Port, Item, Country, Connection, ClientStatus, State, Client, SpecialClient, TUser, Person, Student, Organizer, Class, Enrollment, Hen, Chick) class SelectRelatedRegressTests(TestCase): def test_regression_7110(self): """ Regression test for bug #7110. When using select_related(), we must query the Device and Building tables using two different aliases (each) in order to differentiate the start and end Connection fields. The net result is that both the "connections = ..." queries here should give the same results without pulling in more than the absolute minimum number of tables (history has shown that it's easy to make a mistake in the implementation and include some unnecessary bonus joins). """ b=Building.objects.create(name='101') dev1=Device.objects.create(name="router", building=b) dev2=Device.objects.create(name="switch", building=b) dev3=Device.objects.create(name="server", building=b) port1=Port.objects.create(port_number='4',device=dev1) port2=Port.objects.create(port_number='7',device=dev2) port3=Port.objects.create(port_number='1',device=dev3) c1=Connection.objects.create(start=port1, end=port2) c2=Connection.objects.create(start=port2, end=port3) connections=Connection.objects.filter(start__device__building=b, end__device__building=b).order_by('id') self.assertEqual([(c.id, six.text_type(c.start), six.text_type(c.end)) for c in connections], [(c1.id, 'router/4', 'switch/7'), (c2.id, 'switch/7', 'server/1')]) connections=Connection.objects.filter(start__device__building=b, end__device__building=b).select_related().order_by('id') self.assertEqual([(c.id, six.text_type(c.start), six.text_type(c.end)) for c in connections], [(c1.id, 'router/4', 'switch/7'), (c2.id, 'switch/7', 'server/1')]) # This final query should only have seven tables (port, device and building # twice each, plus connection once). Thus, 6 joins plus the FROM table. self.assertEqual(str(connections.query).count(" JOIN "), 6) def test_regression_8106(self): """ Regression test for bug #8106. Same sort of problem as the previous test, but this time there are more extra tables to pull in as part of the select_related() and some of them could potentially clash (so need to be kept separate). """ us = TUser.objects.create(name="std") usp = Person.objects.create(user=us) uo = TUser.objects.create(name="org") uop = Person.objects.create(user=uo) s = Student.objects.create(person = usp) o = Organizer.objects.create(person = uop) c = Class.objects.create(org=o) e = Enrollment.objects.create(std=s, cls=c) e_related = Enrollment.objects.all().select_related()[0] self.assertEqual(e_related.std.person.user.name, "std") self.assertEqual(e_related.cls.org.person.user.name, "org") def test_regression_8036(self): """ Regression test for bug #8036 the first related model in the tests below ("state") is empty and we try to select the more remotely related state__country. The regression here was not skipping the empty column results for country before getting status. """ australia = Country.objects.create(name='Australia') active = ClientStatus.objects.create(name='active') client = Client.objects.create(name='client', status=active) self.assertEqual(client.status, active) self.assertEqual(Client.objects.select_related()[0].status, active) self.assertEqual(Client.objects.select_related('state')[0].status, active) self.assertEqual(Client.objects.select_related('state', 'status')[0].status, active) self.assertEqual(Client.objects.select_related('state__country')[0].status, active) self.assertEqual(Client.objects.select_related('state__country', 'status')[0].status, active) self.assertEqual(Client.objects.select_related('status')[0].status, active) def test_multi_table_inheritance(self): """ Exercising select_related() with multi-table model inheritance. """ c1 = Child.objects.create(name="child1", value=42) i1 = Item.objects.create(name="item1", child=c1) i2 = Item.objects.create(name="item2") self.assertQuerysetEqual( Item.objects.select_related("child").order_by("name"), ["", ""] ) def test_regression_12851(self): """ Regression for #12851 Deferred fields are used correctly if you select_related a subset of fields. """ australia = Country.objects.create(name='Australia') active = ClientStatus.objects.create(name='active') wa = State.objects.create(name="Western Australia", country=australia) c1 = Client.objects.create(name='Brian Burke', state=wa, status=active) burke = Client.objects.select_related('state').defer('state__name').get(name='Brian Burke') self.assertEqual(burke.name, 'Brian Burke') self.assertEqual(burke.state.name, 'Western Australia') # Still works if we're dealing with an inherited class sc1 = SpecialClient.objects.create(name='Troy Buswell', state=wa, status=active, value=42) troy = SpecialClient.objects.select_related('state').defer('state__name').get(name='Troy Buswell') self.assertEqual(troy.name, 'Troy Buswell') self.assertEqual(troy.value, 42) self.assertEqual(troy.state.name, 'Western Australia') # Still works if we defer an attribute on the inherited class troy = SpecialClient.objects.select_related('state').defer('value', 'state__name').get(name='Troy Buswell') self.assertEqual(troy.name, 'Troy Buswell') self.assertEqual(troy.value, 42) self.assertEqual(troy.state.name, 'Western Australia') # Also works if you use only, rather than defer troy = SpecialClient.objects.select_related('state').only('name', 'state').get(name='Troy Buswell') self.assertEqual(troy.name, 'Troy Buswell') self.assertEqual(troy.value, 42) self.assertEqual(troy.state.name, 'Western Australia') def test_null_join_promotion(self): australia = Country.objects.create(name='Australia') active = ClientStatus.objects.create(name='active') wa = State.objects.create(name="Western Australia", country=australia) bob = Client.objects.create(name='Bob', status=active) jack = Client.objects.create(name='Jack', status=active, state=wa) qs = Client.objects.filter(state=wa).select_related('state') with self.assertNumQueries(1): self.assertEqual(list(qs), [jack]) self.assertEqual(qs[0].state, wa) # The select_related join wasn't promoted as there was already an # existing (even if trimmed) inner join to state. self.assertFalse('LEFT OUTER' in str(qs.query)) qs = Client.objects.select_related('state').order_by('name') with self.assertNumQueries(1): self.assertEqual(list(qs), [bob, jack]) self.assertIs(qs[0].state, None) self.assertEqual(qs[1].state, wa) # The select_related join was promoted as there is already an # existing join. self.assertTrue('LEFT OUTER' in str(qs.query)) def test_regression_19870(self): """ Regression for #19870 """ hen = Hen.objects.create(name='Hen') chick = Chick.objects.create(name='Chick', mother=hen) self.assertEqual(Chick.objects.all()[0].mother.name, 'Hen') self.assertEqual(Chick.objects.select_related()[0].mother.name, 'Hen') def test_regression_22508(self): building = Building.objects.create(name='101') device = Device.objects.create(name="router", building=building) Port.objects.create(port_number='1', device=device) device = Device.objects.get() port = device.port_set.select_related('device__building').get() with self.assertNumQueries(0): port.device.building Django-1.6.11/tests/select_related_regress/models.py0000664000175000017500000000553012502407523022123 0ustar timtim00000000000000from __future__ import unicode_literals from django.db import models from django.utils.encoding import python_2_unicode_compatible @python_2_unicode_compatible class Building(models.Model): name = models.CharField(max_length=10) def __str__(self): return "Building: %s" % self.name @python_2_unicode_compatible class Device(models.Model): building = models.ForeignKey('Building') name = models.CharField(max_length=10) def __str__(self): return "device '%s' in building %s" % (self.name, self.building) @python_2_unicode_compatible class Port(models.Model): device = models.ForeignKey('Device') port_number = models.CharField(max_length=10) def __str__(self): return "%s/%s" % (self.device.name, self.port_number) @python_2_unicode_compatible class Connection(models.Model): start = models.ForeignKey(Port, related_name='connection_start', unique=True) end = models.ForeignKey(Port, related_name='connection_end', unique=True) def __str__(self): return "%s to %s" % (self.start, self.end) # Another non-tree hierarchy that exercises code paths similar to the above # example, but in a slightly different configuration. class TUser(models.Model): name = models.CharField(max_length=200) class Person(models.Model): user = models.ForeignKey(TUser, unique=True) class Organizer(models.Model): person = models.ForeignKey(Person) class Student(models.Model): person = models.ForeignKey(Person) class Class(models.Model): org = models.ForeignKey(Organizer) class Enrollment(models.Model): std = models.ForeignKey(Student) cls = models.ForeignKey(Class) # Models for testing bug #8036. class Country(models.Model): name = models.CharField(max_length=50) class State(models.Model): name = models.CharField(max_length=50) country = models.ForeignKey(Country) class ClientStatus(models.Model): name = models.CharField(max_length=50) class Client(models.Model): name = models.CharField(max_length=50) state = models.ForeignKey(State, null=True) status = models.ForeignKey(ClientStatus) class SpecialClient(Client): value = models.IntegerField() # Some model inheritance exercises @python_2_unicode_compatible class Parent(models.Model): name = models.CharField(max_length=10) def __str__(self): return self.name class Child(Parent): value = models.IntegerField() @python_2_unicode_compatible class Item(models.Model): name = models.CharField(max_length=10) child = models.ForeignKey(Child, null=True) def __str__(self): return self.name # Models for testing bug #19870. @python_2_unicode_compatible class Fowl(models.Model): name = models.CharField(max_length=10) def __str__(self): return self.name class Hen(Fowl): pass class Chick(Fowl): mother = models.ForeignKey(Hen) Django-1.6.11/tests/test_discovery_sample/0000775000175000017500000000000012502407547020167 5ustar timtim00000000000000Django-1.6.11/tests/test_discovery_sample/pattern_tests.py0000664000175000017500000000016112477341424023440 0ustar timtim00000000000000from unittest import TestCase class Test(TestCase): def test_sample(self): self.assertEqual(1, 1) Django-1.6.11/tests/test_discovery_sample/tests_sample.py0000664000175000017500000000071012502407523023234 0ustar timtim00000000000000from unittest import TestCase as UnitTestCase from django.test import TestCase as DjangoTestCase from django.utils.unittest import TestCase as UT2TestCase class TestVanillaUnittest(UnitTestCase): def test_sample(self): self.assertEqual(1, 1) class TestUnittest2(UT2TestCase): def test_sample(self): self.assertEqual(1, 1) class TestDjangoTestCase(DjangoTestCase): def test_sample(self): self.assertEqual(1, 1) Django-1.6.11/tests/test_discovery_sample/__init__.py0000664000175000017500000000000012477341424022270 0ustar timtim00000000000000Django-1.6.11/tests/test_discovery_sample/tests/0000775000175000017500000000000012502407547021331 5ustar timtim00000000000000Django-1.6.11/tests/test_discovery_sample/tests/__init__.py0000664000175000017500000000000012477341424023432 0ustar timtim00000000000000Django-1.6.11/tests/test_discovery_sample/tests/tests.py0000664000175000017500000000013712477341424023050 0ustar timtim00000000000000from unittest import TestCase class Test(TestCase): def test_sample(self): pass Django-1.6.11/tests/middleware_exceptions/0000775000175000017500000000000012502407547020136 5ustar timtim00000000000000Django-1.6.11/tests/middleware_exceptions/views.py0000664000175000017500000000116212502407523021637 0ustar timtim00000000000000from django import http from django.core.exceptions import PermissionDenied from django.template import Template from django.template.response import TemplateResponse def normal_view(request): return http.HttpResponse('OK') def template_response(request): return TemplateResponse(request, Template('OK')) def template_response_error(request): return TemplateResponse(request, Template('{%')) def not_found(request): raise http.Http404() def server_error(request): raise Exception('Error in view') def null_view(request): return None def permission_denied(request): raise PermissionDenied() Django-1.6.11/tests/middleware_exceptions/urls.py0000664000175000017500000000117412502407523021472 0ustar timtim00000000000000# coding: utf-8 from __future__ import absolute_import from django.conf.urls import patterns from . import views urlpatterns = patterns('', (r'^middleware_exceptions/view/$', views.normal_view), (r'^middleware_exceptions/not_found/$', views.not_found), (r'^middleware_exceptions/error/$', views.server_error), (r'^middleware_exceptions/null_view/$', views.null_view), (r'^middleware_exceptions/permission_denied/$', views.permission_denied), (r'^middleware_exceptions/template_response/$', views.template_response), (r'^middleware_exceptions/template_response_error/$', views.template_response_error), ) Django-1.6.11/tests/middleware_exceptions/__init__.py0000664000175000017500000000000012477341424022237 0ustar timtim00000000000000Django-1.6.11/tests/middleware_exceptions/tests.py0000664000175000017500000011514312502407523021651 0ustar timtim00000000000000import sys from django.conf import settings from django.core.signals import got_request_exception from django.http import HttpResponse from django.template.response import TemplateResponse from django.template import Template from django.test import TestCase class TestException(Exception): pass # A middleware base class that tracks which methods have been called class TestMiddleware(object): def __init__(self): self.process_request_called = False self.process_view_called = False self.process_response_called = False self.process_template_response_called = False self.process_exception_called = False def process_request(self, request): self.process_request_called = True def process_view(self, request, view_func, view_args, view_kwargs): self.process_view_called = True def process_template_response(self, request, response): self.process_template_response_called = True return response def process_response(self, request, response): self.process_response_called = True return response def process_exception(self, request, exception): self.process_exception_called = True # Middleware examples that do the right thing class RequestMiddleware(TestMiddleware): def process_request(self, request): super(RequestMiddleware, self).process_request(request) return HttpResponse('Request Middleware') class ViewMiddleware(TestMiddleware): def process_view(self, request, view_func, view_args, view_kwargs): super(ViewMiddleware, self).process_view(request, view_func, view_args, view_kwargs) return HttpResponse('View Middleware') class ResponseMiddleware(TestMiddleware): def process_response(self, request, response): super(ResponseMiddleware, self).process_response(request, response) return HttpResponse('Response Middleware') class TemplateResponseMiddleware(TestMiddleware): def process_template_response(self, request, response): super(TemplateResponseMiddleware, self).process_template_response(request, response) return TemplateResponse(request, Template('Template Response Middleware')) class ExceptionMiddleware(TestMiddleware): def process_exception(self, request, exception): super(ExceptionMiddleware, self).process_exception(request, exception) return HttpResponse('Exception Middleware') # Sample middlewares that raise exceptions class BadRequestMiddleware(TestMiddleware): def process_request(self, request): super(BadRequestMiddleware, self).process_request(request) raise TestException('Test Request Exception') class BadViewMiddleware(TestMiddleware): def process_view(self, request, view_func, view_args, view_kwargs): super(BadViewMiddleware, self).process_view(request, view_func, view_args, view_kwargs) raise TestException('Test View Exception') class BadTemplateResponseMiddleware(TestMiddleware): def process_template_response(self, request, response): super(BadTemplateResponseMiddleware, self).process_template_response(request, response) raise TestException('Test Template Response Exception') class BadResponseMiddleware(TestMiddleware): def process_response(self, request, response): super(BadResponseMiddleware, self).process_response(request, response) raise TestException('Test Response Exception') class BadExceptionMiddleware(TestMiddleware): def process_exception(self, request, exception): super(BadExceptionMiddleware, self).process_exception(request, exception) raise TestException('Test Exception Exception') class BaseMiddlewareExceptionTest(TestCase): urls = 'middleware_exceptions.urls' def setUp(self): self.exceptions = [] got_request_exception.connect(self._on_request_exception) self.client.handler.load_middleware() def tearDown(self): got_request_exception.disconnect(self._on_request_exception) self.exceptions = [] def _on_request_exception(self, sender, request, **kwargs): self.exceptions.append(sys.exc_info()) def _add_middleware(self, middleware): self.client.handler._request_middleware.insert(0, middleware.process_request) self.client.handler._view_middleware.insert(0, middleware.process_view) self.client.handler._template_response_middleware.append(middleware.process_template_response) self.client.handler._response_middleware.append(middleware.process_response) self.client.handler._exception_middleware.append(middleware.process_exception) def assert_exceptions_handled(self, url, errors, extra_error=None): try: response = self.client.get(url) except TestException: # Test client intentionally re-raises any exceptions being raised # during request handling. Hence actual testing that exception was # properly handled is done by relying on got_request_exception # signal being sent. pass except Exception as e: if type(extra_error) != type(e): self.fail("Unexpected exception: %s" % e) self.assertEqual(len(self.exceptions), len(errors)) for i, error in enumerate(errors): exception, value, tb = self.exceptions[i] self.assertEqual(value.args, (error, )) def assert_middleware_usage(self, middleware, request, view, template_response, response, exception): self.assertEqual(middleware.process_request_called, request) self.assertEqual(middleware.process_view_called, view) self.assertEqual(middleware.process_template_response_called, template_response) self.assertEqual(middleware.process_response_called, response) self.assertEqual(middleware.process_exception_called, exception) class MiddlewareTests(BaseMiddlewareExceptionTest): def test_process_request_middleware(self): pre_middleware = TestMiddleware() middleware = RequestMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/view/', []) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, False, False, True, False) self.assert_middleware_usage(middleware, True, False, False, True, False) self.assert_middleware_usage(post_middleware, False, False, False, True, False) def test_process_view_middleware(self): pre_middleware = TestMiddleware() middleware = ViewMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/view/', []) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, True, False) self.assert_middleware_usage(middleware, True, True, False, True, False) self.assert_middleware_usage(post_middleware, True, False, False, True, False) def test_process_response_middleware(self): pre_middleware = TestMiddleware() middleware = ResponseMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/view/', []) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, True, False) self.assert_middleware_usage(middleware, True, True, False, True, False) self.assert_middleware_usage(post_middleware, True, True, False, True, False) def test_process_template_response_middleware(self): pre_middleware = TestMiddleware() middleware = TemplateResponseMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/template_response/', []) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, True, True, False) self.assert_middleware_usage(middleware, True, True, True, True, False) self.assert_middleware_usage(post_middleware, True, True, True, True, False) def test_process_exception_middleware(self): pre_middleware = TestMiddleware() middleware = ExceptionMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/view/', []) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, True, False) self.assert_middleware_usage(middleware, True, True, False, True, False) self.assert_middleware_usage(post_middleware, True, True, False, True, False) def test_process_request_middleware_not_found(self): pre_middleware = TestMiddleware() middleware = RequestMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/not_found/', []) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, False, False, True, False) self.assert_middleware_usage(middleware, True, False, False, True, False) self.assert_middleware_usage(post_middleware, False, False, False, True, False) def test_process_view_middleware_not_found(self): pre_middleware = TestMiddleware() middleware = ViewMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/not_found/', []) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, True, False) self.assert_middleware_usage(middleware, True, True, False, True, False) self.assert_middleware_usage(post_middleware, True, False, False, True, False) def test_process_template_response_middleware_not_found(self): pre_middleware = TestMiddleware() middleware = TemplateResponseMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/not_found/', []) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, True, True) self.assert_middleware_usage(middleware, True, True, False, True, True) self.assert_middleware_usage(post_middleware, True, True, False, True, True) def test_process_response_middleware_not_found(self): pre_middleware = TestMiddleware() middleware = ResponseMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/not_found/', []) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, True, True) self.assert_middleware_usage(middleware, True, True, False, True, True) self.assert_middleware_usage(post_middleware, True, True, False, True, True) def test_process_exception_middleware_not_found(self): pre_middleware = TestMiddleware() middleware = ExceptionMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/not_found/', []) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, True, False) self.assert_middleware_usage(middleware, True, True, False, True, True) self.assert_middleware_usage(post_middleware, True, True, False, True, True) def test_process_request_middleware_exception(self): pre_middleware = TestMiddleware() middleware = RequestMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/error/', []) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, False, False, True, False) self.assert_middleware_usage(middleware, True, False, False, True, False) self.assert_middleware_usage(post_middleware, False, False, False, True, False) def test_process_view_middleware_exception(self): pre_middleware = TestMiddleware() middleware = ViewMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/error/', []) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, True, False) self.assert_middleware_usage(middleware, True, True, False, True, False) self.assert_middleware_usage(post_middleware, True, False, False, True, False) def test_process_response_middleware_exception(self): pre_middleware = TestMiddleware() middleware = ResponseMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/error/', ['Error in view'], Exception()) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, True, True) self.assert_middleware_usage(middleware, True, True, False, True, True) self.assert_middleware_usage(post_middleware, True, True, False, True, True) def test_process_exception_middleware_exception(self): pre_middleware = TestMiddleware() middleware = ExceptionMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/error/', []) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, True, False) self.assert_middleware_usage(middleware, True, True, False, True, True) self.assert_middleware_usage(post_middleware, True, True, False, True, True) def test_process_request_middleware_null_view(self): pre_middleware = TestMiddleware() middleware = RequestMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/null_view/', []) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, False, False, True, False) self.assert_middleware_usage(middleware, True, False, False, True, False) self.assert_middleware_usage(post_middleware, False, False, False, True, False) def test_process_view_middleware_null_view(self): pre_middleware = TestMiddleware() middleware = ViewMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/null_view/', []) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, True, False) self.assert_middleware_usage(middleware, True, True, False, True, False) self.assert_middleware_usage(post_middleware, True, False, False, True, False) def test_process_response_middleware_null_view(self): pre_middleware = TestMiddleware() middleware = ResponseMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/null_view/', [ "The view middleware_exceptions.views.null_view didn't return an HttpResponse object.", ], ValueError()) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, True, False) self.assert_middleware_usage(middleware, True, True, False, True, False) self.assert_middleware_usage(post_middleware, True, True, False, True, False) def test_process_exception_middleware_null_view(self): pre_middleware = TestMiddleware() middleware = ExceptionMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/null_view/', [ "The view middleware_exceptions.views.null_view didn't return an HttpResponse object." ], ValueError()) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, True, False) self.assert_middleware_usage(middleware, True, True, False, True, False) self.assert_middleware_usage(post_middleware, True, True, False, True, False) def test_process_request_middleware_permission_denied(self): pre_middleware = TestMiddleware() middleware = RequestMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/permission_denied/', []) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, False, False, True, False) self.assert_middleware_usage(middleware, True, False, False, True, False) self.assert_middleware_usage(post_middleware, False, False, False, True, False) def test_process_view_middleware_permission_denied(self): pre_middleware = TestMiddleware() middleware = ViewMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/permission_denied/', []) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, True, False) self.assert_middleware_usage(middleware, True, True, False, True, False) self.assert_middleware_usage(post_middleware, True, False, False, True, False) def test_process_response_middleware_permission_denied(self): pre_middleware = TestMiddleware() middleware = ResponseMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/permission_denied/', []) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, True, True) self.assert_middleware_usage(middleware, True, True, False, True, True) self.assert_middleware_usage(post_middleware, True, True, False, True, True) def test_process_exception_middleware_permission_denied(self): pre_middleware = TestMiddleware() middleware = ExceptionMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/permission_denied/', []) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, True, False) self.assert_middleware_usage(middleware, True, True, False, True, True) self.assert_middleware_usage(post_middleware, True, True, False, True, True) def test_process_template_response_error(self): middleware = TestMiddleware() self._add_middleware(middleware) self.assert_exceptions_handled('/middleware_exceptions/template_response_error/', []) # Check that the right middleware methods have been invoked self.assert_middleware_usage(middleware, True, True, True, True, False) class BadMiddlewareTests(BaseMiddlewareExceptionTest): def test_process_request_bad_middleware(self): pre_middleware = TestMiddleware() bad_middleware = BadRequestMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(bad_middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/view/', ['Test Request Exception']) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, False, False, True, False) self.assert_middleware_usage(bad_middleware, True, False, False, True, False) self.assert_middleware_usage(post_middleware, False, False, False, True, False) def test_process_view_bad_middleware(self): pre_middleware = TestMiddleware() bad_middleware = BadViewMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(bad_middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/view/', ['Test View Exception']) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, True, False) self.assert_middleware_usage(bad_middleware, True, True, False, True, False) self.assert_middleware_usage(post_middleware, True, False, False, True, False) def test_process_template_response_bad_middleware(self): pre_middleware = TestMiddleware() bad_middleware = BadTemplateResponseMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(bad_middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/template_response/', ['Test Template Response Exception']) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, True, False) self.assert_middleware_usage(bad_middleware, True, True, True, True, False) self.assert_middleware_usage(post_middleware, True, True, True, True, False) def test_process_response_bad_middleware(self): pre_middleware = TestMiddleware() bad_middleware = BadResponseMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(bad_middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/view/', ['Test Response Exception']) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, False, False) self.assert_middleware_usage(bad_middleware, True, True, False, True, False) self.assert_middleware_usage(post_middleware, True, True, False, True, False) def test_process_exception_bad_middleware(self): pre_middleware = TestMiddleware() bad_middleware = BadExceptionMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(bad_middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/view/', []) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, True, False) self.assert_middleware_usage(bad_middleware, True, True, False, True, False) self.assert_middleware_usage(post_middleware, True, True, False, True, False) def test_process_request_bad_middleware_not_found(self): pre_middleware = TestMiddleware() bad_middleware = BadRequestMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(bad_middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/not_found/', ['Test Request Exception']) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, False, False, True, False) self.assert_middleware_usage(bad_middleware, True, False, False, True, False) self.assert_middleware_usage(post_middleware, False, False, False, True, False) def test_process_view_bad_middleware_not_found(self): pre_middleware = TestMiddleware() bad_middleware = BadViewMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(bad_middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/not_found/', ['Test View Exception']) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, True, False) self.assert_middleware_usage(bad_middleware, True, True, False, True, False) self.assert_middleware_usage(post_middleware, True, False, False, True, False) def test_process_response_bad_middleware_not_found(self): pre_middleware = TestMiddleware() bad_middleware = BadResponseMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(bad_middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/not_found/', ['Test Response Exception']) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, False, True) self.assert_middleware_usage(bad_middleware, True, True, False, True, True) self.assert_middleware_usage(post_middleware, True, True, False, True, True) def test_process_exception_bad_middleware_not_found(self): pre_middleware = TestMiddleware() bad_middleware = BadExceptionMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(bad_middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/not_found/', ['Test Exception Exception']) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, True, False) self.assert_middleware_usage(bad_middleware, True, True, False, True, True) self.assert_middleware_usage(post_middleware, True, True, False, True, True) def test_process_request_bad_middleware_exception(self): pre_middleware = TestMiddleware() bad_middleware = BadRequestMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(bad_middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/error/', ['Test Request Exception']) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, False, False, True, False) self.assert_middleware_usage(bad_middleware, True, False, False, True, False) self.assert_middleware_usage(post_middleware, False, False, False, True, False) def test_process_view_bad_middleware_exception(self): pre_middleware = TestMiddleware() bad_middleware = BadViewMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(bad_middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/error/', ['Test View Exception']) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, True, False) self.assert_middleware_usage(bad_middleware, True, True, False, True, False) self.assert_middleware_usage(post_middleware, True, False, False, True, False) def test_process_response_bad_middleware_exception(self): pre_middleware = TestMiddleware() bad_middleware = BadResponseMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(bad_middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/error/', ['Error in view', 'Test Response Exception']) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, False, True) self.assert_middleware_usage(bad_middleware, True, True, False, True, True) self.assert_middleware_usage(post_middleware, True, True, False, True, True) def test_process_exception_bad_middleware_exception(self): pre_middleware = TestMiddleware() bad_middleware = BadExceptionMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(bad_middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/error/', ['Test Exception Exception']) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, True, False) self.assert_middleware_usage(bad_middleware, True, True, False, True, True) self.assert_middleware_usage(post_middleware, True, True, False, True, True) def test_process_request_bad_middleware_null_view(self): pre_middleware = TestMiddleware() bad_middleware = BadRequestMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(bad_middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/null_view/', ['Test Request Exception']) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, False, False, True, False) self.assert_middleware_usage(bad_middleware, True, False, False, True, False) self.assert_middleware_usage(post_middleware, False, False, False, True, False) def test_process_view_bad_middleware_null_view(self): pre_middleware = TestMiddleware() bad_middleware = BadViewMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(bad_middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/null_view/', ['Test View Exception']) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, True, False) self.assert_middleware_usage(bad_middleware, True, True, False, True, False) self.assert_middleware_usage(post_middleware, True, False, False, True, False) def test_process_response_bad_middleware_null_view(self): pre_middleware = TestMiddleware() bad_middleware = BadResponseMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(bad_middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/null_view/', [ "The view middleware_exceptions.views.null_view didn't return an HttpResponse object.", 'Test Response Exception' ]) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, False, False) self.assert_middleware_usage(bad_middleware, True, True, False, True, False) self.assert_middleware_usage(post_middleware, True, True, False, True, False) def test_process_exception_bad_middleware_null_view(self): pre_middleware = TestMiddleware() bad_middleware = BadExceptionMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(bad_middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/null_view/', [ "The view middleware_exceptions.views.null_view didn't return an HttpResponse object." ], ValueError()) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, True, False) self.assert_middleware_usage(bad_middleware, True, True, False, True, False) self.assert_middleware_usage(post_middleware, True, True, False, True, False) def test_process_request_bad_middleware_permission_denied(self): pre_middleware = TestMiddleware() bad_middleware = BadRequestMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(bad_middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/permission_denied/', ['Test Request Exception']) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, False, False, True, False) self.assert_middleware_usage(bad_middleware, True, False, False, True, False) self.assert_middleware_usage(post_middleware, False, False, False, True, False) def test_process_view_bad_middleware_permission_denied(self): pre_middleware = TestMiddleware() bad_middleware = BadViewMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(bad_middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/permission_denied/', ['Test View Exception']) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, True, False) self.assert_middleware_usage(bad_middleware, True, True, False, True, False) self.assert_middleware_usage(post_middleware, True, False, False, True, False) def test_process_response_bad_middleware_permission_denied(self): pre_middleware = TestMiddleware() bad_middleware = BadResponseMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(bad_middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/permission_denied/', ['Test Response Exception']) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, False, True) self.assert_middleware_usage(bad_middleware, True, True, False, True, True) self.assert_middleware_usage(post_middleware, True, True, False, True, True) def test_process_exception_bad_middleware_permission_denied(self): pre_middleware = TestMiddleware() bad_middleware = BadExceptionMiddleware() post_middleware = TestMiddleware() self._add_middleware(post_middleware) self._add_middleware(bad_middleware) self._add_middleware(pre_middleware) self.assert_exceptions_handled('/middleware_exceptions/permission_denied/', ['Test Exception Exception']) # Check that the right middleware methods have been invoked self.assert_middleware_usage(pre_middleware, True, True, False, True, False) self.assert_middleware_usage(bad_middleware, True, True, False, True, True) self.assert_middleware_usage(post_middleware, True, True, False, True, True) _missing = object() class RootUrlconfTests(TestCase): urls = 'middleware_exceptions.urls' def test_missing_root_urlconf(self): try: original_ROOT_URLCONF = settings.ROOT_URLCONF del settings.ROOT_URLCONF except AttributeError: original_ROOT_URLCONF = _missing self.assertRaises(AttributeError, self.client.get, "/middleware_exceptions/view/" ) if original_ROOT_URLCONF is not _missing: settings.ROOT_URLCONF = original_ROOT_URLCONF Django-1.6.11/tests/middleware_exceptions/models.py0000664000175000017500000000000012502407523021753 0ustar timtim00000000000000Django-1.6.11/tests/m2m_multiple/0000775000175000017500000000000012502407547016166 5ustar timtim00000000000000Django-1.6.11/tests/m2m_multiple/__init__.py0000664000175000017500000000000012477341424020267 0ustar timtim00000000000000Django-1.6.11/tests/m2m_multiple/tests.py0000664000175000017500000000452112502407523017676 0ustar timtim00000000000000from __future__ import absolute_import from datetime import datetime from django.test import TestCase from .models import Article, Category class M2MMultipleTests(TestCase): def test_multiple(self): c1, c2, c3, c4 = [ Category.objects.create(name=name) for name in ["Sports", "News", "Crime", "Life"] ] a1 = Article.objects.create( headline="Area man steals", pub_date=datetime(2005, 11, 27) ) a1.primary_categories.add(c2, c3) a1.secondary_categories.add(c4) a2 = Article.objects.create( headline="Area man runs", pub_date=datetime(2005, 11, 28) ) a2.primary_categories.add(c1, c2) a2.secondary_categories.add(c4) self.assertQuerysetEqual( a1.primary_categories.all(), [ "Crime", "News", ], lambda c: c.name ) self.assertQuerysetEqual( a2.primary_categories.all(), [ "News", "Sports", ], lambda c: c.name ) self.assertQuerysetEqual( a1.secondary_categories.all(), [ "Life", ], lambda c: c.name ) self.assertQuerysetEqual( c1.primary_article_set.all(), [ "Area man runs", ], lambda a: a.headline ) self.assertQuerysetEqual( c1.secondary_article_set.all(), [] ) self.assertQuerysetEqual( c2.primary_article_set.all(), [ "Area man steals", "Area man runs", ], lambda a: a.headline ) self.assertQuerysetEqual( c2.secondary_article_set.all(), [] ) self.assertQuerysetEqual( c3.primary_article_set.all(), [ "Area man steals", ], lambda a: a.headline ) self.assertQuerysetEqual( c3.secondary_article_set.all(), [] ) self.assertQuerysetEqual( c4.primary_article_set.all(), [] ) self.assertQuerysetEqual( c4.secondary_article_set.all(), [ "Area man steals", "Area man runs", ], lambda a: a.headline ) Django-1.6.11/tests/m2m_multiple/models.py0000664000175000017500000000175012502407523020020 0ustar timtim00000000000000""" 20. Multiple many-to-many relationships between the same two tables In this example, an ``Article`` can have many "primary" ``Category`` objects and many "secondary" ``Category`` objects. Set ``related_name`` to designate what the reverse relationship is called. """ from django.db import models from django.utils.encoding import python_2_unicode_compatible @python_2_unicode_compatible class Category(models.Model): name = models.CharField(max_length=20) class Meta: ordering = ('name',) def __str__(self): return self.name @python_2_unicode_compatible class Article(models.Model): headline = models.CharField(max_length=50) pub_date = models.DateTimeField() primary_categories = models.ManyToManyField(Category, related_name='primary_article_set') secondary_categories = models.ManyToManyField(Category, related_name='secondary_article_set') class Meta: ordering = ('pub_date',) def __str__(self): return self.headline Django-1.6.11/tests/validation/0000775000175000017500000000000012502407547015712 5ustar timtim00000000000000Django-1.6.11/tests/validation/test_custom_messages.py0000664000175000017500000000100012502407523022505 0ustar timtim00000000000000from __future__ import absolute_import from . import ValidationTestCase from .models import CustomMessagesModel class CustomMessagesTest(ValidationTestCase): def test_custom_simple_validator_message(self): cmm = CustomMessagesModel(number=12) self.assertFieldFailsValidationWithMessage(cmm.full_clean, 'number', ['AAARGH']) def test_custom_null_message(self): cmm = CustomMessagesModel() self.assertFieldFailsValidationWithMessage(cmm.full_clean, 'number', ['NULL']) Django-1.6.11/tests/validation/test_validators.py0000664000175000017500000000146312502407523021471 0ustar timtim00000000000000from __future__ import absolute_import, unicode_literals from . import ValidationTestCase from .models import ModelToValidate class TestModelsWithValidators(ValidationTestCase): def test_custom_validator_passes_for_correct_value(self): mtv = ModelToValidate(number=10, name='Some Name', f_with_custom_validator=42) self.assertEqual(None, mtv.full_clean()) def test_custom_validator_raises_error_for_incorrect_value(self): mtv = ModelToValidate(number=10, name='Some Name', f_with_custom_validator=12) self.assertFailsValidation(mtv.full_clean, ['f_with_custom_validator']) self.assertFieldFailsValidationWithMessage( mtv.full_clean, 'f_with_custom_validator', ['This is not the answer to life, universe and everything!'] ) Django-1.6.11/tests/validation/__init__.py0000664000175000017500000000116712502407523020022 0ustar timtim00000000000000from django.core.exceptions import ValidationError from django.test import TestCase class ValidationTestCase(TestCase): def assertFailsValidation(self, clean, failed_fields): with self.assertRaises(ValidationError) as cm: clean() self.assertEqual(sorted(failed_fields), sorted(cm.exception.message_dict)) def assertFieldFailsValidationWithMessage(self, clean, field_name, message): with self.assertRaises(ValidationError) as cm: clean() self.assertIn(field_name, cm.exception.message_dict) self.assertEqual(message, cm.exception.message_dict[field_name]) Django-1.6.11/tests/validation/tests.py0000664000175000017500000001630612502407523017426 0ustar timtim00000000000000from __future__ import absolute_import, unicode_literals from django import forms from django.core.exceptions import NON_FIELD_ERRORS from django.test import TestCase from . import ValidationTestCase from .models import (Author, Article, ModelToValidate, GenericIPAddressTestModel, GenericIPAddrUnpackUniqueTest) class BaseModelValidationTests(ValidationTestCase): def test_missing_required_field_raises_error(self): mtv = ModelToValidate(f_with_custom_validator=42) self.assertFailsValidation(mtv.full_clean, ['name', 'number']) def test_with_correct_value_model_validates(self): mtv = ModelToValidate(number=10, name='Some Name') self.assertEqual(None, mtv.full_clean()) def test_custom_validate_method(self): mtv = ModelToValidate(number=11) self.assertFailsValidation(mtv.full_clean, [NON_FIELD_ERRORS, 'name']) def test_wrong_FK_value_raises_error(self): mtv=ModelToValidate(number=10, name='Some Name', parent_id=3) self.assertFailsValidation(mtv.full_clean, ['parent']) def test_correct_FK_value_validates(self): parent = ModelToValidate.objects.create(number=10, name='Some Name') mtv = ModelToValidate(number=10, name='Some Name', parent_id=parent.pk) self.assertEqual(None, mtv.full_clean()) def test_limited_FK_raises_error(self): # The limit_choices_to on the parent field says that a parent object's # number attribute must be 10, so this should fail validation. parent = ModelToValidate.objects.create(number=11, name='Other Name') mtv = ModelToValidate(number=10, name='Some Name', parent_id=parent.pk) self.assertFailsValidation(mtv.full_clean, ['parent']) def test_wrong_email_value_raises_error(self): mtv = ModelToValidate(number=10, name='Some Name', email='not-an-email') self.assertFailsValidation(mtv.full_clean, ['email']) def test_correct_email_value_passes(self): mtv = ModelToValidate(number=10, name='Some Name', email='valid@email.com') self.assertEqual(None, mtv.full_clean()) def test_wrong_url_value_raises_error(self): mtv = ModelToValidate(number=10, name='Some Name', url='not a url') self.assertFieldFailsValidationWithMessage(mtv.full_clean, 'url', ['Enter a valid URL.']) def test_text_greater_that_charfields_max_length_raises_erros(self): mtv = ModelToValidate(number=10, name='Some Name'*100) self.assertFailsValidation(mtv.full_clean, ['name']) def test_malformed_slug_raises_error(self): mtv = ModelToValidate(number=10, name='Some Name', slug='##invalid##') self.assertFailsValidation(mtv.full_clean, ['slug']) class ArticleForm(forms.ModelForm): class Meta: model = Article exclude = ['author'] class ModelFormsTests(TestCase): def setUp(self): self.author = Author.objects.create(name='Joseph Kocherhans') def test_partial_validation(self): # Make sure the "commit=False and set field values later" idiom still # works with model validation. data = { 'title': 'The state of model validation', 'pub_date': '2010-1-10 14:49:00' } form = ArticleForm(data) self.assertEqual(list(form.errors), []) article = form.save(commit=False) article.author = self.author article.save() def test_validation_with_empty_blank_field(self): # Since a value for pub_date wasn't provided and the field is # blank=True, model-validation should pass. # Also, Article.clean() should be run, so pub_date will be filled after # validation, so the form should save cleanly even though pub_date is # not allowed to be null. data = { 'title': 'The state of model validation', } article = Article(author_id=self.author.id) form = ArticleForm(data, instance=article) self.assertEqual(list(form.errors), []) self.assertNotEqual(form.instance.pub_date, None) article = form.save() def test_validation_with_invalid_blank_field(self): # Even though pub_date is set to blank=True, an invalid value was # provided, so it should fail validation. data = { 'title': 'The state of model validation', 'pub_date': 'never' } article = Article(author_id=self.author.id) form = ArticleForm(data, instance=article) self.assertEqual(list(form.errors), ['pub_date']) class GenericIPAddressFieldTests(ValidationTestCase): def test_correct_generic_ip_passes(self): giptm = GenericIPAddressTestModel(generic_ip="1.2.3.4") self.assertIsNone(giptm.full_clean()) giptm = GenericIPAddressTestModel(generic_ip="2001::2") self.assertIsNone(giptm.full_clean()) def test_invalid_generic_ip_raises_error(self): giptm = GenericIPAddressTestModel(generic_ip="294.4.2.1") self.assertFailsValidation(giptm.full_clean, ['generic_ip',]) giptm = GenericIPAddressTestModel(generic_ip="1:2") self.assertFailsValidation(giptm.full_clean, ['generic_ip',]) def test_correct_v4_ip_passes(self): giptm = GenericIPAddressTestModel(v4_ip="1.2.3.4") self.assertIsNone(giptm.full_clean()) def test_invalid_v4_ip_raises_error(self): giptm = GenericIPAddressTestModel(v4_ip="294.4.2.1") self.assertFailsValidation(giptm.full_clean, ['v4_ip',]) giptm = GenericIPAddressTestModel(v4_ip="2001::2") self.assertFailsValidation(giptm.full_clean, ['v4_ip',]) def test_correct_v6_ip_passes(self): giptm = GenericIPAddressTestModel(v6_ip="2001::2") self.assertIsNone(giptm.full_clean()) def test_invalid_v6_ip_raises_error(self): giptm = GenericIPAddressTestModel(v6_ip="1.2.3.4") self.assertFailsValidation(giptm.full_clean, ['v6_ip',]) giptm = GenericIPAddressTestModel(v6_ip="1:2") self.assertFailsValidation(giptm.full_clean, ['v6_ip',]) def test_v6_uniqueness_detection(self): # These two addresses are the same with different syntax giptm = GenericIPAddressTestModel(generic_ip="2001::1:0:0:0:0:2") giptm.save() giptm = GenericIPAddressTestModel(generic_ip="2001:0:1:2") self.assertFailsValidation(giptm.full_clean, ['generic_ip',]) def test_v4_unpack_uniqueness_detection(self): # These two are different, because we are not doing IPv4 unpacking giptm = GenericIPAddressTestModel(generic_ip="::ffff:10.10.10.10") giptm.save() giptm = GenericIPAddressTestModel(generic_ip="10.10.10.10") self.assertIsNone(giptm.full_clean()) # These two are the same, because we are doing IPv4 unpacking giptm = GenericIPAddrUnpackUniqueTest(generic_v4unpack_ip="::ffff:18.52.18.52") giptm.save() giptm = GenericIPAddrUnpackUniqueTest(generic_v4unpack_ip="18.52.18.52") self.assertFailsValidation(giptm.full_clean, ['generic_v4unpack_ip',]) def test_empty_generic_ip_passes(self): giptm = GenericIPAddressTestModel(generic_ip="") self.assertIsNone(giptm.full_clean()) giptm = GenericIPAddressTestModel(generic_ip=None) self.assertIsNone(giptm.full_clean()) Django-1.6.11/tests/validation/test_error_messages.py0000664000175000017500000000747012502407523022345 0ustar timtim00000000000000# -*- encoding: utf-8 -*- from __future__ import unicode_literals from django.core.exceptions import ValidationError from django.db import models from django.utils import six from django.utils.unittest import TestCase class ValidationMessagesTest(TestCase): def _test_validation_messages(self, field, value, expected): with self.assertRaises(ValidationError) as cm: field.clean(value, None) self.assertEqual(cm.exception.messages, expected) def test_autofield_field_raises_error_message(self): f = models.AutoField(primary_key=True) self._test_validation_messages(f, 'fõo', ["'fõo' value must be an integer."]) # primary_key must be True. Refs #12467. with six.assertRaisesRegex(self, AssertionError, "AutoFields must have primary_key=True."): models.AutoField(primary_key=False) def test_integer_field_raises_error_message(self): f = models.IntegerField() self._test_validation_messages(f, 'fõo', ["'fõo' value must be an integer."]) def test_boolean_field_raises_error_message(self): f = models.BooleanField() self._test_validation_messages(f, 'fõo', ["'fõo' value must be either True or False."]) def test_float_field_raises_error_message(self): f = models.FloatField() self._test_validation_messages(f, 'fõo', ["'fõo' value must be a float."]) def test_decimal_field_raises_error_message(self): f = models.DecimalField() self._test_validation_messages(f, 'fõo', ["'fõo' value must be a decimal number."]) def test_null_boolean_field_raises_error_message(self): f = models.NullBooleanField() self._test_validation_messages(f, 'fõo', ["'fõo' value must be either None, True or False."]) def test_date_field_raises_error_message(self): f = models.DateField() self._test_validation_messages(f, 'fõo', ["'fõo' value has an invalid date format. " "It must be in YYYY-MM-DD format."]) self._test_validation_messages(f, 'aaaa-10-10', ["'aaaa-10-10' value has an invalid date format. " "It must be in YYYY-MM-DD format."]) self._test_validation_messages(f, '2011-13-10', ["'2011-13-10' value has the correct format (YYYY-MM-DD) " "but it is an invalid date."]) self._test_validation_messages(f, '2011-10-32', ["'2011-10-32' value has the correct format (YYYY-MM-DD) " "but it is an invalid date."]) def test_datetime_field_raises_error_message(self): f = models.DateTimeField() # Wrong format self._test_validation_messages(f, 'fõo', ["'fõo' value has an invalid format. It must be " "in YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] format."]) # Correct format but invalid date self._test_validation_messages(f, '2011-10-32', ["'2011-10-32' value has the correct format " "(YYYY-MM-DD) but it is an invalid date."]) # Correct format but invalid date/time self._test_validation_messages(f, '2011-10-32 10:10', ["'2011-10-32 10:10' value has the correct format " "(YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]) " "but it is an invalid date/time."]) def test_time_field_raises_error_message(self): f = models.TimeField() # Wrong format self._test_validation_messages(f, 'fõo', ["'fõo' value has an invalid format. It must be in " "HH:MM[:ss[.uuuuuu]] format."]) # Correct format but invalid time self._test_validation_messages(f, '25:50', ["'25:50' value has the correct format " "(HH:MM[:ss[.uuuuuu]]) but it is an invalid time."]) Django-1.6.11/tests/validation/test_unique.py0000664000175000017500000001344212502407523020627 0ustar timtim00000000000000from __future__ import absolute_import, unicode_literals import datetime from django.core.exceptions import ValidationError from django.test import TestCase from django.utils import unittest from .models import (CustomPKModel, UniqueTogetherModel, UniqueFieldsModel, UniqueForDateModel, ModelToValidate, Post, FlexibleDatePost, UniqueErrorsModel) class GetUniqueCheckTests(unittest.TestCase): def test_unique_fields_get_collected(self): m = UniqueFieldsModel() self.assertEqual( ([(UniqueFieldsModel, ('id',)), (UniqueFieldsModel, ('unique_charfield',)), (UniqueFieldsModel, ('unique_integerfield',))], []), m._get_unique_checks() ) def test_unique_together_gets_picked_up_and_converted_to_tuple(self): m = UniqueTogetherModel() self.assertEqual( ([(UniqueTogetherModel, ('ifield', 'cfield',)), (UniqueTogetherModel, ('ifield', 'efield')), (UniqueTogetherModel, ('id',)), ], []), m._get_unique_checks() ) def test_primary_key_is_considered_unique(self): m = CustomPKModel() self.assertEqual(([(CustomPKModel, ('my_pk_field',))], []), m._get_unique_checks()) def test_unique_for_date_gets_picked_up(self): m = UniqueForDateModel() self.assertEqual(( [(UniqueForDateModel, ('id',))], [(UniqueForDateModel, 'date', 'count', 'start_date'), (UniqueForDateModel, 'year', 'count', 'end_date'), (UniqueForDateModel, 'month', 'order', 'end_date')] ), m._get_unique_checks() ) def test_unique_for_date_exclusion(self): m = UniqueForDateModel() self.assertEqual(( [(UniqueForDateModel, ('id',))], [(UniqueForDateModel, 'year', 'count', 'end_date'), (UniqueForDateModel, 'month', 'order', 'end_date')] ), m._get_unique_checks(exclude='start_date') ) class PerformUniqueChecksTest(TestCase): def test_primary_key_unique_check_not_performed_when_adding_and_pk_not_specified(self): # Regression test for #12560 with self.assertNumQueries(0): mtv = ModelToValidate(number=10, name='Some Name') setattr(mtv, '_adding', True) mtv.full_clean() def test_primary_key_unique_check_performed_when_adding_and_pk_specified(self): # Regression test for #12560 with self.assertNumQueries(1): mtv = ModelToValidate(number=10, name='Some Name', id=123) setattr(mtv, '_adding', True) mtv.full_clean() def test_primary_key_unique_check_not_performed_when_not_adding(self): # Regression test for #12132 with self.assertNumQueries(0): mtv = ModelToValidate(number=10, name='Some Name') mtv.full_clean() def test_unique_for_date(self): p1 = Post.objects.create(title="Django 1.0 is released", slug="Django 1.0", subtitle="Finally", posted=datetime.date(2008, 9, 3)) p = Post(title="Django 1.0 is released", posted=datetime.date(2008, 9, 3)) with self.assertRaises(ValidationError) as cm: p.full_clean() self.assertEqual(cm.exception.message_dict, {'title': ['Title must be unique for Posted date.']}) # Should work without errors p = Post(title="Work on Django 1.1 begins", posted=datetime.date(2008, 9, 3)) p.full_clean() # Should work without errors p = Post(title="Django 1.0 is released", posted=datetime.datetime(2008, 9,4)) p.full_clean() p = Post(slug="Django 1.0", posted=datetime.datetime(2008, 1, 1)) with self.assertRaises(ValidationError) as cm: p.full_clean() self.assertEqual(cm.exception.message_dict, {'slug': ['Slug must be unique for Posted year.']}) p = Post(subtitle="Finally", posted=datetime.datetime(2008, 9, 30)) with self.assertRaises(ValidationError) as cm: p.full_clean() self.assertEqual(cm.exception.message_dict, {'subtitle': ['Subtitle must be unique for Posted month.']}) p = Post(title="Django 1.0 is released") with self.assertRaises(ValidationError) as cm: p.full_clean() self.assertEqual(cm.exception.message_dict, {'posted': ['This field cannot be null.']}) def test_unique_for_date_with_nullable_date(self): p1 = FlexibleDatePost.objects.create(title="Django 1.0 is released", slug="Django 1.0", subtitle="Finally", posted=datetime.date(2008, 9, 3)) p = FlexibleDatePost(title="Django 1.0 is released") try: p.full_clean() except ValidationError: self.fail("unique_for_date checks shouldn't trigger when the associated DateField is None.") p = FlexibleDatePost(slug="Django 1.0") try: p.full_clean() except ValidationError: self.fail("unique_for_year checks shouldn't trigger when the associated DateField is None.") p = FlexibleDatePost(subtitle="Finally") try: p.full_clean() except ValidationError: self.fail("unique_for_month checks shouldn't trigger when the associated DateField is None.") def test_unique_errors(self): m1 = UniqueErrorsModel.objects.create(name='Some Name', no=10) m = UniqueErrorsModel(name='Some Name', no=11) with self.assertRaises(ValidationError) as cm: m.full_clean() self.assertEqual(cm.exception.message_dict, {'name': ['Custom unique name message.']}) m = UniqueErrorsModel(name='Some Other Name', no=10) with self.assertRaises(ValidationError) as cm: m.full_clean() self.assertEqual(cm.exception.message_dict, {'no': ['Custom unique number message.']}) Django-1.6.11/tests/validation/models.py0000664000175000017500000001057512502407523017551 0ustar timtim00000000000000from __future__ import unicode_literals from datetime import datetime from django.core.exceptions import ValidationError from django.db import models from django.utils.encoding import python_2_unicode_compatible def validate_answer_to_universe(value): if value != 42: raise ValidationError('This is not the answer to life, universe and everything!', code='not42') class ModelToValidate(models.Model): name = models.CharField(max_length=100) created = models.DateTimeField(default=datetime.now) number = models.IntegerField(db_column='number_val') parent = models.ForeignKey('self', blank=True, null=True, limit_choices_to={'number': 10}) email = models.EmailField(blank=True) url = models.URLField(blank=True) f_with_custom_validator = models.IntegerField(blank=True, null=True, validators=[validate_answer_to_universe]) slug = models.SlugField(blank=True) def clean(self): super(ModelToValidate, self).clean() if self.number == 11: raise ValidationError('Invalid number supplied!') class UniqueFieldsModel(models.Model): unique_charfield = models.CharField(max_length=100, unique=True) unique_integerfield = models.IntegerField(unique=True) non_unique_field = models.IntegerField() class CustomPKModel(models.Model): my_pk_field = models.CharField(max_length=100, primary_key=True) class UniqueTogetherModel(models.Model): cfield = models.CharField(max_length=100) ifield = models.IntegerField() efield = models.EmailField() class Meta: unique_together = (('ifield', 'cfield',), ['ifield', 'efield']) class UniqueForDateModel(models.Model): start_date = models.DateField() end_date = models.DateTimeField() count = models.IntegerField(unique_for_date="start_date", unique_for_year="end_date") order = models.IntegerField(unique_for_month="end_date") name = models.CharField(max_length=100) class CustomMessagesModel(models.Model): other = models.IntegerField(blank=True, null=True) number = models.IntegerField(db_column='number_val', error_messages={'null': 'NULL', 'not42': 'AAARGH', 'not_equal': '%s != me'}, validators=[validate_answer_to_universe] ) class Author(models.Model): name = models.CharField(max_length=100) class Article(models.Model): title = models.CharField(max_length=100) author = models.ForeignKey(Author) pub_date = models.DateTimeField(blank=True) def clean(self): if self.pub_date is None: self.pub_date = datetime.now() @python_2_unicode_compatible class Post(models.Model): title = models.CharField(max_length=50, unique_for_date='posted', blank=True) slug = models.CharField(max_length=50, unique_for_year='posted', blank=True) subtitle = models.CharField(max_length=50, unique_for_month='posted', blank=True) posted = models.DateField() def __str__(self): return self.name class FlexibleDatePost(models.Model): title = models.CharField(max_length=50, unique_for_date='posted', blank=True) slug = models.CharField(max_length=50, unique_for_year='posted', blank=True) subtitle = models.CharField(max_length=50, unique_for_month='posted', blank=True) posted = models.DateField(blank=True, null=True) class UniqueErrorsModel(models.Model): name = models.CharField(max_length=100, unique=True, error_messages={'unique': 'Custom unique name message.'}) no = models.IntegerField(unique=True, error_messages={'unique': 'Custom unique number message.'}) class GenericIPAddressTestModel(models.Model): generic_ip = models.GenericIPAddressField(blank=True, null=True, unique=True) v4_ip = models.GenericIPAddressField(blank=True, null=True, protocol="ipv4") v6_ip = models.GenericIPAddressField(blank=True, null=True, protocol="ipv6") ip_verbose_name = models.GenericIPAddressField("IP Address Verbose", blank=True, null=True) class GenericIPAddrUnpackUniqueTest(models.Model): generic_v4unpack_ip = models.GenericIPAddressField(null=True, blank=True, unique=True, unpack_ipv4=True) # A model can't have multiple AutoFields # Refs #12467. assertion_error = None try: class MultipleAutoFields(models.Model): auto1 = models.AutoField(primary_key=True) auto2 = models.AutoField(primary_key=True) except AssertionError as exc: assertion_error = exc assert str(assertion_error) == "A model can't have more than one AutoField." Django-1.6.11/tests/many_to_one_regress/0000775000175000017500000000000012502407547017621 5ustar timtim00000000000000Django-1.6.11/tests/many_to_one_regress/__init__.py0000664000175000017500000000000012502406330021705 0ustar timtim00000000000000Django-1.6.11/tests/many_to_one_regress/tests.py0000664000175000017500000001254712502407523021340 0ustar timtim00000000000000from __future__ import absolute_import from django.db import models from django.test import TestCase from django.utils import six from .models import ( First, Third, Parent, Child, Category, Record, Relation, Car, Driver) class ManyToOneRegressionTests(TestCase): def test_object_creation(self): Third.objects.create(id='3', name='An example') parent = Parent(name='fred') parent.save() Child.objects.create(name='bam-bam', parent=parent) def test_fk_assignment_and_related_object_cache(self): # Tests of ForeignKey assignment and the related-object cache (see #6886). p = Parent.objects.create(name="Parent") c = Child.objects.create(name="Child", parent=p) # Look up the object again so that we get a "fresh" object. c = Child.objects.get(name="Child") p = c.parent # Accessing the related object again returns the exactly same object. self.assertTrue(c.parent is p) # But if we kill the cache, we get a new object. del c._parent_cache self.assertFalse(c.parent is p) # Assigning a new object results in that object getting cached immediately. p2 = Parent.objects.create(name="Parent 2") c.parent = p2 self.assertTrue(c.parent is p2) # Assigning None succeeds if field is null=True. p.bestchild = None self.assertTrue(p.bestchild is None) # bestchild should still be None after saving. p.save() self.assertTrue(p.bestchild is None) # bestchild should still be None after fetching the object again. p = Parent.objects.get(name="Parent") self.assertTrue(p.bestchild is None) # Assigning None fails: Child.parent is null=False. self.assertRaises(ValueError, setattr, c, "parent", None) # You also can't assign an object of the wrong type here self.assertRaises(ValueError, setattr, c, "parent", First(id=1, second=1)) # Nor can you explicitly assign None to Child.parent during object # creation (regression for #9649). self.assertRaises(ValueError, Child, name='xyzzy', parent=None) self.assertRaises(ValueError, Child.objects.create, name='xyzzy', parent=None) # Creation using keyword argument should cache the related object. p = Parent.objects.get(name="Parent") c = Child(parent=p) self.assertTrue(c.parent is p) # Creation using keyword argument and unsaved related instance (#8070). p = Parent() c = Child(parent=p) self.assertTrue(c.parent is p) # Creation using attname keyword argument and an id will cause the # related object to be fetched. p = Parent.objects.get(name="Parent") c = Child(parent_id=p.id) self.assertFalse(c.parent is p) self.assertEqual(c.parent, p) def test_multiple_foreignkeys(self): # Test of multiple ForeignKeys to the same model (bug #7125). c1 = Category.objects.create(name='First') c2 = Category.objects.create(name='Second') c3 = Category.objects.create(name='Third') r1 = Record.objects.create(category=c1) r2 = Record.objects.create(category=c1) r3 = Record.objects.create(category=c2) r4 = Record.objects.create(category=c2) r5 = Record.objects.create(category=c3) r = Relation.objects.create(left=r1, right=r2) r = Relation.objects.create(left=r3, right=r4) r = Relation.objects.create(left=r1, right=r3) r = Relation.objects.create(left=r5, right=r2) r = Relation.objects.create(left=r3, right=r2) q1 = Relation.objects.filter(left__category__name__in=['First'], right__category__name__in=['Second']) self.assertQuerysetEqual(q1, [""]) q2 = Category.objects.filter(record__left_set__right__category__name='Second').order_by('name') self.assertQuerysetEqual(q2, ["", ""]) p = Parent.objects.create(name="Parent") c = Child.objects.create(name="Child", parent=p) self.assertRaises(ValueError, Child.objects.create, name="Grandchild", parent=c) def test_fk_instantiation_outside_model(self): # Regression for #12190 -- Should be able to instantiate a FK outside # of a model, and interrogate its related field. cat = models.ForeignKey(Category) self.assertEqual('id', cat.rel.get_related_field().name) def test_relation_unsaved(self): # Test that the _set manager does not join on Null value fields (#17541) Third.objects.create(name='Third 1') Third.objects.create(name='Third 2') th = Third(name="testing") # The object isn't saved an thus the relation field is null - we won't even # execute a query in this case. with self.assertNumQueries(0): self.assertEqual(th.child_set.count(), 0) th.save() # Now the model is saved, so we will need to execute an query. with self.assertNumQueries(1): self.assertEqual(th.child_set.count(), 0) def test_related_null_to_field(self): c1 = Car.objects.create() c2 = Car.objects.create() d1 = Driver.objects.create() self.assertIs(d1.car, None) with self.assertNumQueries(0): self.assertEqual(list(c1.drivers.all()), []) Django-1.6.11/tests/many_to_one_regress/models.py0000664000175000017500000000333312502407523021452 0ustar timtim00000000000000""" Regression tests for a few ForeignKey bugs. """ from __future__ import unicode_literals from django.db import models from django.utils.encoding import python_2_unicode_compatible # If ticket #1578 ever slips back in, these models will not be able to be # created (the field names being lower-cased versions of their opposite # classes is important here). class First(models.Model): second = models.IntegerField() class Second(models.Model): first = models.ForeignKey(First, related_name = 'the_first') # Protect against repetition of #1839, #2415 and #2536. class Third(models.Model): name = models.CharField(max_length=20) third = models.ForeignKey('self', null=True, related_name='child_set') class Parent(models.Model): name = models.CharField(max_length=20) bestchild = models.ForeignKey('Child', null=True, related_name='favored_by') class Child(models.Model): name = models.CharField(max_length=20) parent = models.ForeignKey(Parent) # Multiple paths to the same model (#7110, #7125) @python_2_unicode_compatible class Category(models.Model): name = models.CharField(max_length=20) def __str__(self): return self.name class Record(models.Model): category = models.ForeignKey(Category) @python_2_unicode_compatible class Relation(models.Model): left = models.ForeignKey(Record, related_name='left_set') right = models.ForeignKey(Record, related_name='right_set') def __str__(self): return "%s - %s" % (self.left.category.name, self.right.category.name) class Car(models.Model): make = models.CharField(max_length=100, null=True, unique=True) class Driver(models.Model): car = models.ForeignKey(Car, to_field='make', null=True, related_name='drivers') Django-1.6.11/tests/admin_scripts/0000775000175000017500000000000012502407547016417 5ustar timtim00000000000000Django-1.6.11/tests/admin_scripts/simple_app/0000775000175000017500000000000012502407547020550 5ustar timtim00000000000000Django-1.6.11/tests/admin_scripts/simple_app/__init__.py0000664000175000017500000000000012477341424022651 0ustar timtim00000000000000Django-1.6.11/tests/admin_scripts/simple_app/models.py0000664000175000017500000000012112502407523022371 0ustar timtim00000000000000from __future__ import absolute_import from ..complex_app.models.bar import Bar Django-1.6.11/tests/admin_scripts/urls.py0000664000175000017500000000045312502406330017745 0ustar timtim00000000000000import os from django.conf.urls import patterns from django.utils._os import upath here = os.path.dirname(upath(__file__)) urlpatterns = patterns('', (r'^custom_templates/(?P.*)$', 'django.views.static.serve', { 'document_root': os.path.join(here, 'custom_templates'), }), ) Django-1.6.11/tests/admin_scripts/management/0000775000175000017500000000000012502407547020533 5ustar timtim00000000000000Django-1.6.11/tests/admin_scripts/management/commands/0000775000175000017500000000000012502407547022334 5ustar timtim00000000000000Django-1.6.11/tests/admin_scripts/management/commands/base_command.py0000664000175000017500000000122512502407523025310 0ustar timtim00000000000000from optparse import make_option from django.core.management.base import BaseCommand class Command(BaseCommand): option_list = BaseCommand.option_list + ( make_option('--option_a','-a', action='store', dest='option_a', default='1'), make_option('--option_b','-b', action='store', dest='option_b', default='2'), make_option('--option_c','-c', action='store', dest='option_c', default='3'), ) help = 'Test basic commands' requires_model_validation = False args = '[labels ...]' def handle(self, *labels, **options): print('EXECUTE:BaseCommand labels=%s, options=%s' % (labels, sorted(options.items()))) Django-1.6.11/tests/admin_scripts/management/commands/custom_startproject.py0000664000175000017500000000054512502407523027022 0ustar timtim00000000000000from optparse import make_option from django.core.management.commands.startproject import Command as BaseCommand class Command(BaseCommand): option_list = BaseCommand.option_list + ( make_option('--extra', action='store', dest='extra', help='An arbitrary extra value passed to the context'), ) Django-1.6.11/tests/admin_scripts/management/commands/noargs_command.py0000664000175000017500000000042512502407523025670 0ustar timtim00000000000000from django.core.management.base import NoArgsCommand class Command(NoArgsCommand): help = "Test No-args commands" requires_model_validation = False def handle_noargs(self, **options): print('EXECUTE:NoArgsCommand options=%s' % sorted(options.items())) Django-1.6.11/tests/admin_scripts/management/commands/__init__.py0000664000175000017500000000000012477341424024435 0ustar timtim00000000000000Django-1.6.11/tests/admin_scripts/management/commands/label_command.py0000664000175000017500000000050312502407523025453 0ustar timtim00000000000000from django.core.management.base import LabelCommand class Command(LabelCommand): help = "Test Label-based commands" requires_model_validation = False args = '