summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/modeltests/basic/models.py11
-rw-r--r--tests/modeltests/model_forms/models.py43
-rw-r--r--tests/modeltests/mutually_referential/models.py8
-rw-r--r--tests/modeltests/ordering/models.py4
-rw-r--r--tests/regressiontests/datastructures/tests.py8
-rw-r--r--tests/regressiontests/datatypes/models.py26
-rw-r--r--tests/regressiontests/decorators/__init__.py0
-rw-r--r--tests/regressiontests/decorators/models.py2
-rw-r--r--tests/regressiontests/decorators/tests.py56
-rw-r--r--tests/regressiontests/fixtures_regress/fixtures/absolute.json9
-rw-r--r--tests/regressiontests/fixtures_regress/models.py22
-rw-r--r--tests/regressiontests/i18n/misc.py11
-rw-r--r--tests/regressiontests/string_lookup/models.py8
13 files changed, 194 insertions, 14 deletions
diff --git a/tests/modeltests/basic/models.py b/tests/modeltests/basic/models.py
index 2f4b932fe0..557331a36e 100644
--- a/tests/modeltests/basic/models.py
+++ b/tests/modeltests/basic/models.py
@@ -5,6 +5,11 @@
This is a basic model with only two non-primary-key fields.
"""
+try:
+ set
+except NameError:
+ from sets import Set as set
+
from django.db import models
class Article(models.Model):
@@ -389,4 +394,10 @@ year, including Jan. 1 and Dec. 31.
>>> a.save()
>>> Article.objects.get(pk=a.id).headline
u'\u6797\u539f \u3081\u3050\u307f'
+
+# Model instances have a hash function, so they can be used in sets or as
+# dictionary keys. Two models compare as equal if their primary keys are equal.
+>>> s = set([a10, a11, a12])
+>>> Article.objects.get(headline='Article 11') in s
+True
"""
diff --git a/tests/modeltests/model_forms/models.py b/tests/modeltests/model_forms/models.py
index f1fed8f1e1..c480899f84 100644
--- a/tests/modeltests/model_forms/models.py
+++ b/tests/modeltests/model_forms/models.py
@@ -64,11 +64,11 @@ class TextFile(models.Model):
def __unicode__(self):
return self.description
-
+
class ImageFile(models.Model):
description = models.CharField(max_length=20)
image = models.FileField(upload_to=tempfile.gettempdir())
-
+
def __unicode__(self):
return self.description
@@ -155,29 +155,52 @@ familiar with the mechanics.
... class Meta:
... model = Category
->>> class BadForm(CategoryForm):
+>>> class OddForm(CategoryForm):
... class Meta:
... model = Article
-Traceback (most recent call last):
-...
-ImproperlyConfigured: BadForm defines a different model than its parent.
+
+OddForm is now an Article-related thing, because BadForm.Meta overrides
+CategoryForm.Meta.
+>>> OddForm.base_fields.keys()
+['headline', 'slug', 'pub_date', 'writer', 'article', 'status', 'categories']
>>> class ArticleForm(ModelForm):
... class Meta:
... model = Article
+First class with a Meta class wins.
+
>>> class BadForm(ArticleForm, CategoryForm):
... pass
-Traceback (most recent call last):
-...
-ImproperlyConfigured: BadForm's base classes define more than one model.
+>>> OddForm.base_fields.keys()
+['headline', 'slug', 'pub_date', 'writer', 'article', 'status', 'categories']
-This one is OK since the subclass specifies the same model as the parent.
+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).
+>>> class CategoryForm(ModelForm):
+... class Meta:
+... model = Category
>>> class SubCategoryForm(CategoryForm):
+... pass
+>>> SubCategoryForm.base_fields.keys()
+['name', 'slug', 'url']
+
+We can also subclass the Meta inner class to change the fields list.
+
+>>> class CategoryForm(ModelForm):
+... checkbox = forms.BooleanField()
+...
... class Meta:
... model = Category
+>>> class SubCategoryForm(CategoryForm):
+... class Meta(CategoryForm.Meta):
+... exclude = ['url']
+>>> print SubCategoryForm()
+<tr><th><label for="id_name">Name:</label></th><td><input id="id_name" type="text" name="name" maxlength="20" /></td></tr>
+<tr><th><label for="id_slug">Slug:</label></th><td><input id="id_slug" type="text" name="slug" maxlength="20" /></td></tr>
+<tr><th><label for="id_checkbox">Checkbox:</label></th><td><input type="checkbox" name="checkbox" id="id_checkbox" /></td></tr>
# Old form_for_x tests #######################################################
diff --git a/tests/modeltests/mutually_referential/models.py b/tests/modeltests/mutually_referential/models.py
index 7cf7bf8bb2..5176721f3d 100644
--- a/tests/modeltests/mutually_referential/models.py
+++ b/tests/modeltests/mutually_referential/models.py
@@ -1,18 +1,22 @@
"""
24. Mutually referential many-to-one relationships
-To define a many-to-one relationship, use ``ForeignKey()`` .
+Strings can be used instead of model literals to set up "lazy" relations.
"""
from django.db.models import *
class Parent(Model):
name = CharField(max_length=100, core=True)
+
+ # Use a simple string for forward declarations.
bestchild = ForeignKey("Child", null=True, related_name="favoured_by")
class Child(Model):
name = CharField(max_length=100)
- parent = ForeignKey(Parent)
+
+ # You can also explicitally specify the related app.
+ parent = ForeignKey("mutually_referential.Parent")
__test__ = {'API_TESTS':"""
# Create a Parent
diff --git a/tests/modeltests/ordering/models.py b/tests/modeltests/ordering/models.py
index 3e651d4ee7..9b342a9265 100644
--- a/tests/modeltests/ordering/models.py
+++ b/tests/modeltests/ordering/models.py
@@ -2,8 +2,8 @@
6. Specifying ordering
Specify default ordering for a model using the ``ordering`` attribute, which
-should be a list or tuple of field names. This tells Django how to order the
-results of ``get_list()`` and other similar functions.
+should be a list or tuple of field names. This tells Django how to order
+queryset results.
If a field name in ``ordering`` starts with a hyphen, that field will be
ordered in descending order. Otherwise, it'll be ordered in ascending order.
diff --git a/tests/regressiontests/datastructures/tests.py b/tests/regressiontests/datastructures/tests.py
index b5dc5d171b..b51b4b1233 100644
--- a/tests/regressiontests/datastructures/tests.py
+++ b/tests/regressiontests/datastructures/tests.py
@@ -77,6 +77,8 @@ MultiValueDictKeyError: "Key 'lastname' not found in <MultiValueDict: {'position
'not one'
>>> d.keys() == d.copy().keys()
True
+>>> d2 = d.copy()
+>>> d2['four'] = 'four'
>>> print repr(d)
{'one': 'not one', 'two': 'two', 'three': 'three'}
>>> d.pop('one', 'missing')
@@ -99,6 +101,12 @@ Init from sequence of tuples
>>> print repr(d)
{1: 'one', 0: 'zero', 2: 'two'}
+>>> d.clear()
+>>> d
+{}
+>>> d.keyOrder
+[]
+
### DotExpandedDict ############################################################
>>> d = DotExpandedDict({'person.1.firstname': ['Simon'], 'person.1.lastname': ['Willison'], 'person.2.firstname': ['Adrian'], 'person.2.lastname': ['Holovaty']})
diff --git a/tests/regressiontests/datatypes/models.py b/tests/regressiontests/datatypes/models.py
index ff9666bc0c..9ebb6402e2 100644
--- a/tests/regressiontests/datatypes/models.py
+++ b/tests/regressiontests/datatypes/models.py
@@ -56,4 +56,30 @@ datetime.date(1938, 6, 4)
datetime.time(5, 30)
>>> d3.consumed_at
datetime.datetime(2007, 4, 20, 16, 19, 59)
+
+# Year boundary tests (ticket #3689)
+
+>>> d = Donut(name='Date Test 2007', baked_date=datetime.datetime(year=2007, month=12, day=31), consumed_at=datetime.datetime(year=2007, month=12, day=31, hour=23, minute=59, second=59))
+>>> d.save()
+>>> d1 = Donut(name='Date Test 2006', baked_date=datetime.datetime(year=2006, month=1, day=1), consumed_at=datetime.datetime(year=2006, month=1, day=1))
+>>> d1.save()
+
+>>> Donut.objects.filter(baked_date__year=2007)
+[<Donut: Date Test 2007>]
+
+>>> Donut.objects.filter(baked_date__year=2006)
+[<Donut: Date Test 2006>]
+
+>>> Donut.objects.filter(consumed_at__year=2007).order_by('name')
+[<Donut: Apple Fritter>, <Donut: Date Test 2007>]
+
+>>> Donut.objects.filter(consumed_at__year=2006)
+[<Donut: Date Test 2006>]
+
+>>> Donut.objects.filter(consumed_at__year=2005)
+[]
+
+>>> Donut.objects.filter(consumed_at__year=2008)
+[]
+
"""}
diff --git a/tests/regressiontests/decorators/__init__.py b/tests/regressiontests/decorators/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/regressiontests/decorators/__init__.py
diff --git a/tests/regressiontests/decorators/models.py b/tests/regressiontests/decorators/models.py
new file mode 100644
index 0000000000..e5a795067b
--- /dev/null
+++ b/tests/regressiontests/decorators/models.py
@@ -0,0 +1,2 @@
+# A models.py so that tests run.
+
diff --git a/tests/regressiontests/decorators/tests.py b/tests/regressiontests/decorators/tests.py
new file mode 100644
index 0000000000..0c434772f8
--- /dev/null
+++ b/tests/regressiontests/decorators/tests.py
@@ -0,0 +1,56 @@
+from unittest import TestCase
+from sys import version_info
+
+from django.http import HttpResponse
+from django.utils.functional import allow_lazy, lazy, memoize
+from django.views.decorators.http import require_http_methods, require_GET, require_POST
+from django.views.decorators.vary import vary_on_headers, vary_on_cookie
+from django.views.decorators.cache import cache_page, never_cache, cache_control
+from django.contrib.auth.decorators import login_required, permission_required, user_passes_test
+from django.contrib.admin.views.decorators import staff_member_required
+
+def fully_decorated(request):
+ """Expected __doc__"""
+ return HttpResponse('<html><body>dummy</body></html>')
+fully_decorated.anything = "Expected __dict__"
+
+# django.views.decorators.http
+fully_decorated = require_http_methods(["GET"])(fully_decorated)
+fully_decorated = require_GET(fully_decorated)
+fully_decorated = require_POST(fully_decorated)
+
+# django.views.decorators.vary
+fully_decorated = vary_on_headers('Accept-language')(fully_decorated)
+fully_decorated = vary_on_cookie(fully_decorated)
+
+# django.views.decorators.cache
+fully_decorated = cache_page(60*15)(fully_decorated)
+fully_decorated = cache_control(private=True)(fully_decorated)
+fully_decorated = never_cache(fully_decorated)
+
+# django.contrib.auth.decorators
+fully_decorated = user_passes_test(lambda u:True)(fully_decorated)
+fully_decorated = login_required(fully_decorated)
+fully_decorated = permission_required('change_world')(fully_decorated)
+
+# django.contrib.admin.views.decorators
+fully_decorated = staff_member_required(fully_decorated)
+
+# django.utils.functional
+fully_decorated = memoize(fully_decorated, {}, 1)
+fully_decorated = allow_lazy(fully_decorated)
+fully_decorated = lazy(fully_decorated)
+
+class DecoratorsTest(TestCase):
+
+ def test_attributes(self):
+ """
+ Tests that django decorators set certain attributes of the wrapped
+ function.
+ """
+ # Only check __name__ on Python 2.4 or later since __name__ can't be
+ # assigned to in earlier Python versions.
+ if version_info[0] >= 2 and version_info[1] >= 4:
+ self.assertEquals(fully_decorated.__name__, 'fully_decorated')
+ self.assertEquals(fully_decorated.__doc__, 'Expected __doc__')
+ self.assertEquals(fully_decorated.__dict__['anything'], 'Expected __dict__')
diff --git a/tests/regressiontests/fixtures_regress/fixtures/absolute.json b/tests/regressiontests/fixtures_regress/fixtures/absolute.json
new file mode 100644
index 0000000000..37ed3f6886
--- /dev/null
+++ b/tests/regressiontests/fixtures_regress/fixtures/absolute.json
@@ -0,0 +1,9 @@
+[
+ {
+ "pk": "1",
+ "model": "fixtures_regress.absolute",
+ "fields": {
+ "name": "Load Absolute Path Test"
+ }
+ }
+] \ No newline at end of file
diff --git a/tests/regressiontests/fixtures_regress/models.py b/tests/regressiontests/fixtures_regress/models.py
index a62925eb37..144debe05a 100644
--- a/tests/regressiontests/fixtures_regress/models.py
+++ b/tests/regressiontests/fixtures_regress/models.py
@@ -1,6 +1,7 @@
from django.db import models
from django.contrib.auth.models import User
from django.conf import settings
+import os
class Animal(models.Model):
name = models.CharField(max_length=150)
@@ -28,6 +29,16 @@ class Stuff(models.Model):
name = None
return unicode(name) + u' is owned by ' + unicode(self.owner)
+class Absolute(models.Model):
+ name = models.CharField(max_length=40)
+
+ load_count = 0
+
+ def __init__(self, *args, **kwargs):
+ super(Absolute, self).__init__(*args, **kwargs)
+ Absolute.load_count += 1
+
+
__test__ = {'API_TESTS':"""
>>> from django.core import management
@@ -49,4 +60,15 @@ __test__ = {'API_TESTS':"""
>>> Stuff.objects.all()
[<Stuff: None is owned by None>]
+###############################################
+# Regression test for ticket #6436 --
+# os.path.join will throw away the initial parts of a path if it encounters
+# an absolute path. This means that if a fixture is specified as an absolute path,
+# we need to make sure we don't discover the absolute path in every fixture directory.
+
+>>> load_absolute_path = os.path.join(os.path.dirname(__file__), 'fixtures', 'absolute.json')
+>>> management.call_command('loaddata', load_absolute_path, verbosity=0)
+>>> Absolute.load_count
+1
+
"""}
diff --git a/tests/regressiontests/i18n/misc.py b/tests/regressiontests/i18n/misc.py
index eb64263799..6ed8afaee3 100644
--- a/tests/regressiontests/i18n/misc.py
+++ b/tests/regressiontests/i18n/misc.py
@@ -1,3 +1,5 @@
+import sys
+
tests = """
>>> from django.utils.translation.trans_real import parse_accept_lang_header
>>> p = parse_accept_lang_header
@@ -83,7 +85,14 @@ source tree.
>>> r.META = {'HTTP_ACCEPT_LANGUAGE': 'es-ar,de'}
>>> g(r)
'es-ar'
+"""
+# Python 2.3 returns slightly different results for completely bogus locales,
+# so we omit this test for that anything below 2.4. It's relatively harmless in
+# any cases (GIGO). This also means this won't be executed on Jython currently,
+# but life's like that sometimes.
+if sys.version_info >= (2, 4):
+ tests += """
This test assumes there won't be a Django translation to a US variation
of the Spanish language, a safe assumption. When the user sets it
as the preferred language, the main 'es' translation should be selected
@@ -91,7 +100,9 @@ instead.
>>> r.META = {'HTTP_ACCEPT_LANGUAGE': 'es-us'}
>>> g(r)
'es'
+"""
+tests += """
This tests the following scenario: there isn't a main language (zh)
translation of Django but there is a translation to variation (zh_CN)
the user sets zh-cn as the preferred language, it should be selected by
diff --git a/tests/regressiontests/string_lookup/models.py b/tests/regressiontests/string_lookup/models.py
index 9deeb18763..1bdb2d4452 100644
--- a/tests/regressiontests/string_lookup/models.py
+++ b/tests/regressiontests/string_lookup/models.py
@@ -39,6 +39,7 @@ class Base(models.Model):
class Article(models.Model):
name = models.CharField(max_length=50)
text = models.TextField()
+ submitted_from = models.IPAddressField(blank=True, null=True)
def __str__(self):
return "Article %s" % self.name
@@ -98,4 +99,11 @@ __test__ = {'API_TESTS': ur"""
>>> Article.objects.get(text__contains='quick brown fox')
<Article: Article Test>
+
+# Regression test for #708: "like" queries on IP address fields require casting
+# to text (on PostgreSQL).
+>>> Article(name='IP test', text='The body', submitted_from='192.0.2.100').save()
+>>> Article.objects.filter(submitted_from__contains='192.0.2')
+[<Article: Article IP test>]
+
"""}