1 from __future__
import absolute_import
, unicode_literals
4 from operator
import attrgetter
6 from django
.core
.exceptions
import ValidationError
7 from django
.test
import TestCase
, skipUnlessDBFeature
8 from django
.utils
import six
9 from django
.utils
import tzinfo
11 from .models
import (Worker
, Article
, Party
, Event
, Department
,
12 BrokenUnicodeMethod
, NonAutoPK
, Model1
, Model2
, Model3
)
15 class ModelTests(TestCase
):
16 # The bug is that the following queries would raise:
17 # "TypeError: Related Field has invalid lookup: gte"
18 def test_related_gte_lookup(self
):
20 Regression test for #10153: foreign key __gte lookups.
22 Worker
.objects
.filter(department__gte
=0)
24 def test_related_lte_lookup(self
):
26 Regression test for #10153: foreign key __lte lookups.
28 Worker
.objects
.filter(department__lte
=0)
30 def test_empty_choice(self
):
31 # NOTE: Part of the regression test here is merely parsing the model
32 # declaration. The verbose_name, in particular, did not always work.
33 a
= Article
.objects
.create(
34 headline
="Look at me!", pub_date
=datetime
.datetime
.now()
36 # An empty choice field should return None for the display name.
37 self
.assertIs(a
.get_status_display(), None)
39 # Empty strings should be returned as Unicode
40 a
= Article
.objects
.get(pk
=a
.pk
)
41 self
.assertEqual(a
.misc_data
, '')
42 self
.assertIs(type(a
.misc_data
), six
.text_type
)
44 def test_long_textfield(self
):
45 # TextFields can hold more than 4000 characters (this was broken in
47 a
= Article
.objects
.create(
48 headline
="Really, really big",
49 pub_date
=datetime
.datetime
.now(),
50 article_text
="ABCDE" * 1000
52 a
= Article
.objects
.get(pk
=a
.pk
)
53 self
.assertEqual(len(a
.article_text
), 5000)
55 def test_date_lookup(self
):
56 # Regression test for #659
57 Party
.objects
.create(when
=datetime
.datetime(1999, 12, 31))
58 Party
.objects
.create(when
=datetime
.datetime(1998, 12, 31))
59 Party
.objects
.create(when
=datetime
.datetime(1999, 1, 1))
60 self
.assertQuerysetEqual(
61 Party
.objects
.filter(when__month
=2), []
63 self
.assertQuerysetEqual(
64 Party
.objects
.filter(when__month
=1), [
65 datetime
.date(1999, 1, 1)
69 self
.assertQuerysetEqual(
70 Party
.objects
.filter(when__month
=12), [
71 datetime
.date(1999, 12, 31),
72 datetime
.date(1998, 12, 31),
76 self
.assertQuerysetEqual(
77 Party
.objects
.filter(when__year
=1998), [
78 datetime
.date(1998, 12, 31),
82 # Regression test for #8510
83 self
.assertQuerysetEqual(
84 Party
.objects
.filter(when__day
="31"), [
85 datetime
.date(1999, 12, 31),
86 datetime
.date(1998, 12, 31),
90 self
.assertQuerysetEqual(
91 Party
.objects
.filter(when__month
="12"), [
92 datetime
.date(1999, 12, 31),
93 datetime
.date(1998, 12, 31),
97 self
.assertQuerysetEqual(
98 Party
.objects
.filter(when__year
="1998"), [
99 datetime
.date(1998, 12, 31),
104 def test_date_filter_null(self
):
105 # Date filtering was failing with NULL date values in SQLite
106 # (regression test for #3501, amongst other things).
107 Party
.objects
.create(when
=datetime
.datetime(1999, 1, 1))
108 Party
.objects
.create()
109 p
= Party
.objects
.filter(when__month
=1)[0]
110 self
.assertEqual(p
.when
, datetime
.date(1999, 1, 1))
111 self
.assertQuerysetEqual(
112 Party
.objects
.filter(pk
=p
.pk
).dates("when", "month"), [
118 def test_get_next_prev_by_field(self
):
119 # Check that get_next_by_FIELD and get_previous_by_FIELD don't crash
120 # when we have usecs values stored on the database
122 # It crashed after the Field.get_db_prep_* refactor, because on most
123 # backends DateTimeFields supports usecs, but DateTimeField.to_python
124 # didn't recognize them. (Note that
125 # Model._get_next_or_previous_by_FIELD coerces values to strings)
126 Event
.objects
.create(when
=datetime
.datetime(2000, 1, 1, 16, 0, 0))
127 Event
.objects
.create(when
=datetime
.datetime(2000, 1, 1, 6, 1, 1))
128 Event
.objects
.create(when
=datetime
.datetime(2000, 1, 1, 13, 1, 1))
129 e
= Event
.objects
.create(when
=datetime
.datetime(2000, 1, 1, 12, 0, 20, 24))
132 e
.get_next_by_when().when
, datetime
.datetime(2000, 1, 1, 13, 1, 1)
135 e
.get_previous_by_when().when
, datetime
.datetime(2000, 1, 1, 6, 1, 1)
138 def test_primary_key_foreign_key_types(self
):
139 # Check Department and Worker (non-default PK type)
140 d
= Department
.objects
.create(id=10, name
="IT")
141 w
= Worker
.objects
.create(department
=d
, name
="Full-time")
142 self
.assertEqual(six
.text_type(w
), "Full-time")
144 def test_broken_unicode(self
):
145 # Models with broken unicode methods should still have a printable repr
146 b
= BrokenUnicodeMethod
.objects
.create(name
="Jerry")
147 self
.assertEqual(repr(b
), "<BrokenUnicodeMethod: [Bad Unicode data]>")
149 @skipUnlessDBFeature("supports_timezones")
150 def test_timezones(self
):
151 # Saving an updating with timezone-aware datetime Python objects.
152 # Regression test for #10443.
153 # The idea is that all these creations and saving should work without
154 # crashing. It's not rocket science.
155 dt1
= datetime
.datetime(2008, 8, 31, 16, 20, tzinfo
=tzinfo
.FixedOffset(600))
156 dt2
= datetime
.datetime(2008, 8, 31, 17, 20, tzinfo
=tzinfo
.FixedOffset(600))
157 obj
= Article
.objects
.create(
158 headline
="A headline", pub_date
=dt1
, article_text
="foo"
163 Article
.objects
.filter(headline
="A headline").update(pub_date
=dt1
),
167 def test_chained_fks(self
):
169 Regression for #18432: Chained foreign keys with to_field produce incorrect query
172 m1
= Model1
.objects
.create(pkey
=1000)
173 m2
= Model2
.objects
.create(model1
=m1
)
174 m3
= Model3
.objects
.create(model2
=m2
)
176 # this is the actual test for #18432
177 m3
= Model3
.objects
.get(model2
=1000)
181 class ModelValidationTest(TestCase
):
182 def test_pk_validation(self
):
183 one
= NonAutoPK
.objects
.create(name
="one")
184 again
= NonAutoPK(name
="one")
185 self
.assertRaises(ValidationError
, again
.validate_unique
)
188 class EvaluateMethodTest(TestCase
):
190 Regression test for #13640: cannot filter by objects with 'evaluate' attr
193 def test_model_with_evaluate_method(self
):
195 Ensures that you can filter by objects that have an 'evaluate' attr
197 dept
= Department
.objects
.create(pk
=1, name
='abc')
198 dept
.evaluate
= 'abc'
199 Worker
.objects
.filter(department
=dept
)