Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
D
django
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
django
Commits
406675b1
Kaydet (Commit)
406675b1
authored
Şub 05, 2016
tarafından
Tim Graham
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Fixed #26176 -- Fixed E123 flake8 warnings.
üst
27531451
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
528 additions
and
540 deletions
+528
-540
checks.py
django/contrib/admin/checks.py
+0
-0
forms.py
django/contrib/flatpages/forms.py
+9
-5
models.py
django/contrib/flatpages/models.py
+4
-1
raster.py
django/contrib/gis/gdal/prototypes/raster.py
+2
-1
dates.py
django/views/generic/dates.py
+3
-3
setup.cfg
setup.cfg
+1
-1
tests.py
tests/aggregation_regress/tests.py
+0
-0
tests.py
tests/annotations/tests.py
+2
-1
test_functions.py
tests/gis_tests/geoapp/test_functions.py
+0
-0
test_commands.py
tests/gis_tests/gis_migrations/test_commands.py
+3
-4
tests.py
tests/lookup/tests.py
+222
-215
tests.py
tests/many_to_many/tests.py
+144
-121
tests.py
tests/many_to_one/tests.py
+135
-183
test_security.py
tests/middleware/test_security.py
+1
-4
test_writer.py
tests/migrations/test_writer.py
+0
-0
test_response.py
tests/template_tests/test_response.py
+2
-1
No files found.
django/contrib/admin/checks.py
Dosyayı görüntüle @
406675b1
django/contrib/flatpages/forms.py
Dosyayı görüntüle @
406675b1
...
@@ -5,12 +5,16 @@ from django.utils.translation import ugettext, ugettext_lazy as _
...
@@ -5,12 +5,16 @@ from django.utils.translation import ugettext, ugettext_lazy as _
class
FlatpageForm
(
forms
.
ModelForm
):
class
FlatpageForm
(
forms
.
ModelForm
):
url
=
forms
.
RegexField
(
label
=
_
(
"URL"
),
max_length
=
100
,
regex
=
r'^[-\w/\.~]+$'
,
url
=
forms
.
RegexField
(
help_text
=
_
(
"Example: '/about/contact/'. Make sure to have leading"
label
=
_
(
"URL"
),
" and trailing slashes."
),
max_length
=
100
,
regex
=
r'^[-\w/\.~]+$'
,
help_text
=
_
(
"Example: '/about/contact/'. Make sure to have leading and trailing slashes."
),
error_messages
=
{
error_messages
=
{
"invalid"
:
_
(
"This value must contain only letters, numbers,"
"invalid"
:
_
(
" dots, underscores, dashes, slashes or tildes."
),
"This value must contain only letters, numbers, dots, "
"underscores, dashes, slashes or tildes."
),
},
},
)
)
...
...
django/contrib/flatpages/models.py
Dosyayı görüntüle @
406675b1
...
@@ -13,7 +13,10 @@ class FlatPage(models.Model):
...
@@ -13,7 +13,10 @@ class FlatPage(models.Model):
title
=
models
.
CharField
(
_
(
'title'
),
max_length
=
200
)
title
=
models
.
CharField
(
_
(
'title'
),
max_length
=
200
)
content
=
models
.
TextField
(
_
(
'content'
),
blank
=
True
)
content
=
models
.
TextField
(
_
(
'content'
),
blank
=
True
)
enable_comments
=
models
.
BooleanField
(
_
(
'enable comments'
),
default
=
False
)
enable_comments
=
models
.
BooleanField
(
_
(
'enable comments'
),
default
=
False
)
template_name
=
models
.
CharField
(
_
(
'template name'
),
max_length
=
70
,
blank
=
True
,
template_name
=
models
.
CharField
(
_
(
'template name'
),
max_length
=
70
,
blank
=
True
,
help_text
=
_
(
help_text
=
_
(
"Example: 'flatpages/contact_page.html'. If this isn't provided, "
"Example: 'flatpages/contact_page.html'. If this isn't provided, "
"the system will use 'flatpages/default.html'."
"the system will use 'flatpages/default.html'."
...
...
django/contrib/gis/gdal/prototypes/raster.py
Dosyayı görüntüle @
406675b1
...
@@ -62,7 +62,8 @@ get_band_ds = voidptr_output(std_call('GDALGetBandDataset'), [c_void_p])
...
@@ -62,7 +62,8 @@ get_band_ds = voidptr_output(std_call('GDALGetBandDataset'), [c_void_p])
get_band_datatype
=
int_output
(
std_call
(
'GDALGetRasterDataType'
),
[
c_void_p
])
get_band_datatype
=
int_output
(
std_call
(
'GDALGetRasterDataType'
),
[
c_void_p
])
get_band_nodata_value
=
double_output
(
std_call
(
'GDALGetRasterNoDataValue'
),
[
c_void_p
,
POINTER
(
c_int
)])
get_band_nodata_value
=
double_output
(
std_call
(
'GDALGetRasterNoDataValue'
),
[
c_void_p
,
POINTER
(
c_int
)])
set_band_nodata_value
=
void_output
(
std_call
(
'GDALSetRasterNoDataValue'
),
[
c_void_p
,
c_double
])
set_band_nodata_value
=
void_output
(
std_call
(
'GDALSetRasterNoDataValue'
),
[
c_void_p
,
c_double
])
get_band_statistics
=
void_output
(
std_call
(
'GDALGetRasterStatistics'
),
get_band_statistics
=
void_output
(
std_call
(
'GDALGetRasterStatistics'
),
[
[
c_void_p
,
c_int
,
c_int
,
POINTER
(
c_double
),
POINTER
(
c_double
),
c_void_p
,
c_int
,
c_int
,
POINTER
(
c_double
),
POINTER
(
c_double
),
POINTER
(
c_double
),
POINTER
(
c_double
),
c_void_p
,
c_void_p
,
POINTER
(
c_double
),
POINTER
(
c_double
),
c_void_p
,
c_void_p
,
...
...
django/views/generic/dates.py
Dosyayı görüntüle @
406675b1
...
@@ -658,11 +658,11 @@ class BaseDateDetailView(YearMixin, MonthMixin, DayMixin, DateMixin, BaseDetailV
...
@@ -658,11 +658,11 @@ class BaseDateDetailView(YearMixin, MonthMixin, DayMixin, DateMixin, BaseDetailV
if
not
self
.
get_allow_future
()
and
date
>
datetime
.
date
.
today
():
if
not
self
.
get_allow_future
()
and
date
>
datetime
.
date
.
today
():
raise
Http404
(
_
(
raise
Http404
(
_
(
"Future
%(verbose_name_plural)
s not available because "
"Future
%(verbose_name_plural)
s not available because "
"
%(class_name)
s.allow_future is False."
)
%
{
"
%(class_name)
s.allow_future is False."
)
%
{
'verbose_name_plural'
:
qs
.
model
.
_meta
.
verbose_name_plural
,
'verbose_name_plural'
:
qs
.
model
.
_meta
.
verbose_name_plural
,
'class_name'
:
self
.
__class__
.
__name__
,
'class_name'
:
self
.
__class__
.
__name__
,
},
})
)
# Filter down a queryset from self.queryset using the date from the
# Filter down a queryset from self.queryset using the date from the
# URL. This'll get passed as the queryset to DetailView.get_object,
# URL. This'll get passed as the queryset to DetailView.get_object,
...
...
setup.cfg
Dosyayı görüntüle @
406675b1
...
@@ -4,7 +4,7 @@ install-script = scripts/rpm-install.sh
...
@@ -4,7 +4,7 @@ install-script = scripts/rpm-install.sh
[flake8]
[flake8]
exclude = build,.git,./django/utils/lru_cache.py,./django/utils/six.py,./django/conf/app_template/*,./django/dispatch/weakref_backports.py,./tests/.env,./xmlrunner,tests/view_tests/tests/py3_test_debug.py,tests/template_tests/annotated_tag_function.py
exclude = build,.git,./django/utils/lru_cache.py,./django/utils/six.py,./django/conf/app_template/*,./django/dispatch/weakref_backports.py,./tests/.env,./xmlrunner,tests/view_tests/tests/py3_test_debug.py,tests/template_tests/annotated_tag_function.py
ignore = E12
3,E12
8,E402,W503,W601
ignore = E128,E402,W503,W601
max-line-length = 119
max-line-length = 119
[isort]
[isort]
...
...
tests/aggregation_regress/tests.py
Dosyayı görüntüle @
406675b1
tests/annotations/tests.py
Dosyayı görüntüle @
406675b1
...
@@ -428,7 +428,8 @@ class NonAggregateAnnotationTestCase(TestCase):
...
@@ -428,7 +428,8 @@ class NonAggregateAnnotationTestCase(TestCase):
F
(
'ticker_name'
),
F
(
'ticker_name'
),
F
(
'description'
),
F
(
'description'
),
Value
(
'No Tag'
),
Value
(
'No Tag'
),
function
=
'COALESCE'
)
function
=
'COALESCE'
)
)
.
order_by
(
'name'
)
)
.
order_by
(
'name'
)
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
...
...
tests/gis_tests/geoapp/test_functions.py
Dosyayı görüntüle @
406675b1
tests/gis_tests/gis_migrations/test_commands.py
Dosyayı görüntüle @
406675b1
...
@@ -56,10 +56,9 @@ class MigrateTests(TransactionTestCase):
...
@@ -56,10 +56,9 @@ class MigrateTests(TransactionTestCase):
# Not all GIS backends have geometry columns model
# Not all GIS backends have geometry columns model
pass
pass
else
:
else
:
self
.
assertEqual
(
qs
=
GeoColumn
.
objects
.
filter
(
GeoColumn
.
objects
.
filter
(
**
{
'
%
s__in'
%
GeoColumn
.
table_name_col
():
[
"gis_neighborhood"
,
"gis_household"
]}
**
{
'
%
s__in'
%
GeoColumn
.
table_name_col
():
[
"gis_neighborhood"
,
"gis_household"
]}
)
.
count
(),
)
0
)
self
.
assertEqual
(
qs
.
count
(),
0
)
# Revert the "unmigration"
# Revert the "unmigration"
call_command
(
"migrate"
,
"gis_migrations"
,
verbosity
=
0
)
call_command
(
"migrate"
,
"gis_migrations"
,
verbosity
=
0
)
tests/lookup/tests.py
Dosyayı görüntüle @
406675b1
...
@@ -16,34 +16,22 @@ class LookupTests(TestCase):
...
@@ -16,34 +16,22 @@ class LookupTests(TestCase):
def
setUp
(
self
):
def
setUp
(
self
):
# Create a few Authors.
# Create a few Authors.
self
.
au1
=
Author
(
name
=
'Author 1'
)
self
.
au1
=
Author
.
objects
.
create
(
name
=
'Author 1'
)
self
.
au1
.
save
()
self
.
au2
=
Author
.
objects
.
create
(
name
=
'Author 2'
)
self
.
au2
=
Author
(
name
=
'Author 2'
)
self
.
au2
.
save
()
# Create a couple of Articles.
# Create a couple of Articles.
self
.
a1
=
Article
(
headline
=
'Article 1'
,
pub_date
=
datetime
(
2005
,
7
,
26
),
author
=
self
.
au1
)
self
.
a1
=
Article
.
objects
.
create
(
headline
=
'Article 1'
,
pub_date
=
datetime
(
2005
,
7
,
26
),
author
=
self
.
au1
)
self
.
a1
.
save
()
self
.
a2
=
Article
.
objects
.
create
(
headline
=
'Article 2'
,
pub_date
=
datetime
(
2005
,
7
,
27
),
author
=
self
.
au1
)
self
.
a2
=
Article
(
headline
=
'Article 2'
,
pub_date
=
datetime
(
2005
,
7
,
27
),
author
=
self
.
au1
)
self
.
a3
=
Article
.
objects
.
create
(
headline
=
'Article 3'
,
pub_date
=
datetime
(
2005
,
7
,
27
),
author
=
self
.
au1
)
self
.
a2
.
save
()
self
.
a4
=
Article
.
objects
.
create
(
headline
=
'Article 4'
,
pub_date
=
datetime
(
2005
,
7
,
28
),
author
=
self
.
au1
)
self
.
a3
=
Article
(
headline
=
'Article 3'
,
pub_date
=
datetime
(
2005
,
7
,
27
),
author
=
self
.
au1
)
self
.
a5
=
Article
.
objects
.
create
(
headline
=
'Article 5'
,
pub_date
=
datetime
(
2005
,
8
,
1
,
9
,
0
),
author
=
self
.
au2
)
self
.
a3
.
save
()
self
.
a6
=
Article
.
objects
.
create
(
headline
=
'Article 6'
,
pub_date
=
datetime
(
2005
,
8
,
1
,
8
,
0
),
author
=
self
.
au2
)
self
.
a4
=
Article
(
headline
=
'Article 4'
,
pub_date
=
datetime
(
2005
,
7
,
28
),
author
=
self
.
au1
)
self
.
a7
=
Article
.
objects
.
create
(
headline
=
'Article 7'
,
pub_date
=
datetime
(
2005
,
7
,
27
),
author
=
self
.
au2
)
self
.
a4
.
save
()
self
.
a5
=
Article
(
headline
=
'Article 5'
,
pub_date
=
datetime
(
2005
,
8
,
1
,
9
,
0
),
author
=
self
.
au2
)
self
.
a5
.
save
()
self
.
a6
=
Article
(
headline
=
'Article 6'
,
pub_date
=
datetime
(
2005
,
8
,
1
,
8
,
0
),
author
=
self
.
au2
)
self
.
a6
.
save
()
self
.
a7
=
Article
(
headline
=
'Article 7'
,
pub_date
=
datetime
(
2005
,
7
,
27
),
author
=
self
.
au2
)
self
.
a7
.
save
()
# Create a few Tags.
# Create a few Tags.
self
.
t1
=
Tag
(
name
=
'Tag 1'
)
self
.
t1
=
Tag
.
objects
.
create
(
name
=
'Tag 1'
)
self
.
t1
.
save
()
self
.
t1
.
articles
.
add
(
self
.
a1
,
self
.
a2
,
self
.
a3
)
self
.
t1
.
articles
.
add
(
self
.
a1
,
self
.
a2
,
self
.
a3
)
self
.
t2
=
Tag
(
name
=
'Tag 2'
)
self
.
t2
=
Tag
.
objects
.
create
(
name
=
'Tag 2'
)
self
.
t2
.
save
()
self
.
t2
.
articles
.
add
(
self
.
a3
,
self
.
a4
,
self
.
a5
)
self
.
t2
.
articles
.
add
(
self
.
a3
,
self
.
a4
,
self
.
a5
)
self
.
t3
=
Tag
(
name
=
'Tag 3'
)
self
.
t3
=
Tag
.
objects
.
create
(
name
=
'Tag 3'
)
self
.
t3
.
save
()
self
.
t3
.
articles
.
add
(
self
.
a5
,
self
.
a6
,
self
.
a7
)
self
.
t3
.
articles
.
add
(
self
.
a5
,
self
.
a6
,
self
.
a7
)
def
test_exists
(
self
):
def
test_exists
(
self
):
...
@@ -62,7 +50,8 @@ class LookupTests(TestCase):
...
@@ -62,7 +50,8 @@ class LookupTests(TestCase):
@skipUnlessDBFeature
(
'supports_date_lookup_using_string'
)
@skipUnlessDBFeature
(
'supports_date_lookup_using_string'
)
def
test_lookup_date_as_str
(
self
):
def
test_lookup_date_as_str
(
self
):
# A date lookup can be performed using a string search
# A date lookup can be performed using a string search
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
pub_date__startswith
=
'2005'
),
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
pub_date__startswith
=
'2005'
),
[
[
'<Article: Article 5>'
,
'<Article: Article 5>'
,
'<Article: Article 6>'
,
'<Article: Article 6>'
,
...
@@ -71,14 +60,16 @@ class LookupTests(TestCase):
...
@@ -71,14 +60,16 @@ class LookupTests(TestCase):
'<Article: Article 3>'
,
'<Article: Article 3>'
,
'<Article: Article 7>'
,
'<Article: Article 7>'
,
'<Article: Article 1>'
,
'<Article: Article 1>'
,
])
]
)
def
test_iterator
(
self
):
def
test_iterator
(
self
):
# Each QuerySet gets iterator(), which is a generator that "lazily"
# Each QuerySet gets iterator(), which is a generator that "lazily"
# returns results using database-level iteration.
# returns results using database-level iteration.
self
.
assertIsInstance
(
Article
.
objects
.
iterator
(),
collections
.
Iterator
)
self
.
assertIsInstance
(
Article
.
objects
.
iterator
(),
collections
.
Iterator
)
self
.
assertQuerysetEqual
(
Article
.
objects
.
iterator
(),
self
.
assertQuerysetEqual
(
Article
.
objects
.
iterator
(),
[
[
'Article 5'
,
'Article 5'
,
'Article 6'
,
'Article 6'
,
...
@@ -88,7 +79,8 @@ class LookupTests(TestCase):
...
@@ -88,7 +79,8 @@ class LookupTests(TestCase):
'Article 7'
,
'Article 7'
,
'Article 1'
,
'Article 1'
,
],
],
transform
=
attrgetter
(
'headline'
))
transform
=
attrgetter
(
'headline'
)
)
# iterator() can be used on any QuerySet.
# iterator() can be used on any QuerySet.
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__endswith
=
'4'
)
.
iterator
(),
Article
.
objects
.
filter
(
headline__endswith
=
'4'
)
.
iterator
(),
...
@@ -144,7 +136,8 @@ class LookupTests(TestCase):
...
@@ -144,7 +136,8 @@ class LookupTests(TestCase):
# and you can specify which fields you want to retrieve.
# and you can specify which fields you want to retrieve.
def
identity
(
x
):
def
identity
(
x
):
return
x
return
x
self
.
assertQuerysetEqual
(
Article
.
objects
.
values
(
'headline'
),
self
.
assertQuerysetEqual
(
Article
.
objects
.
values
(
'headline'
),
[
[
{
'headline'
:
'Article 5'
},
{
'headline'
:
'Article 5'
},
{
'headline'
:
'Article 6'
},
{
'headline'
:
'Article 6'
},
...
@@ -154,12 +147,15 @@ class LookupTests(TestCase):
...
@@ -154,12 +147,15 @@ class LookupTests(TestCase):
{
'headline'
:
'Article 7'
},
{
'headline'
:
'Article 7'
},
{
'headline'
:
'Article 1'
},
{
'headline'
:
'Article 1'
},
],
],
transform
=
identity
)
transform
=
identity
)
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
pub_date__exact
=
datetime
(
2005
,
7
,
27
))
.
values
(
'id'
),
Article
.
objects
.
filter
(
pub_date__exact
=
datetime
(
2005
,
7
,
27
))
.
values
(
'id'
),
[{
'id'
:
self
.
a2
.
id
},
{
'id'
:
self
.
a3
.
id
},
{
'id'
:
self
.
a7
.
id
}],
[{
'id'
:
self
.
a2
.
id
},
{
'id'
:
self
.
a3
.
id
},
{
'id'
:
self
.
a7
.
id
}],
transform
=
identity
)
transform
=
identity
self
.
assertQuerysetEqual
(
Article
.
objects
.
values
(
'id'
,
'headline'
),
)
self
.
assertQuerysetEqual
(
Article
.
objects
.
values
(
'id'
,
'headline'
),
[
[
{
'id'
:
self
.
a5
.
id
,
'headline'
:
'Article 5'
},
{
'id'
:
self
.
a5
.
id
,
'headline'
:
'Article 5'
},
{
'id'
:
self
.
a6
.
id
,
'headline'
:
'Article 6'
},
{
'id'
:
self
.
a6
.
id
,
'headline'
:
'Article 6'
},
...
@@ -169,10 +165,12 @@ class LookupTests(TestCase):
...
@@ -169,10 +165,12 @@ class LookupTests(TestCase):
{
'id'
:
self
.
a7
.
id
,
'headline'
:
'Article 7'
},
{
'id'
:
self
.
a7
.
id
,
'headline'
:
'Article 7'
},
{
'id'
:
self
.
a1
.
id
,
'headline'
:
'Article 1'
},
{
'id'
:
self
.
a1
.
id
,
'headline'
:
'Article 1'
},
],
],
transform
=
identity
)
transform
=
identity
)
# You can use values() with iterator() for memory savings,
# You can use values() with iterator() for memory savings,
# because iterator() uses database-level iteration.
# because iterator() uses database-level iteration.
self
.
assertQuerysetEqual
(
Article
.
objects
.
values
(
'id'
,
'headline'
)
.
iterator
(),
self
.
assertQuerysetEqual
(
Article
.
objects
.
values
(
'id'
,
'headline'
)
.
iterator
(),
[
[
{
'headline'
:
'Article 5'
,
'id'
:
self
.
a5
.
id
},
{
'headline'
:
'Article 5'
,
'id'
:
self
.
a5
.
id
},
{
'headline'
:
'Article 6'
,
'id'
:
self
.
a6
.
id
},
{
'headline'
:
'Article 6'
,
'id'
:
self
.
a6
.
id
},
...
@@ -182,7 +180,8 @@ class LookupTests(TestCase):
...
@@ -182,7 +180,8 @@ class LookupTests(TestCase):
{
'headline'
:
'Article 7'
,
'id'
:
self
.
a7
.
id
},
{
'headline'
:
'Article 7'
,
'id'
:
self
.
a7
.
id
},
{
'headline'
:
'Article 1'
,
'id'
:
self
.
a1
.
id
},
{
'headline'
:
'Article 1'
,
'id'
:
self
.
a1
.
id
},
],
],
transform
=
identity
)
transform
=
identity
)
# The values() method works with "extra" fields specified in extra(select).
# The values() method works with "extra" fields specified in extra(select).
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
Article
.
objects
.
extra
(
select
=
{
'id_plus_one'
:
'id + 1'
})
.
values
(
'id'
,
'id_plus_one'
),
Article
.
objects
.
extra
(
select
=
{
'id_plus_one'
:
'id + 1'
})
.
values
(
'id'
,
'id_plus_one'
),
...
@@ -195,7 +194,8 @@ class LookupTests(TestCase):
...
@@ -195,7 +194,8 @@ class LookupTests(TestCase):
{
'id'
:
self
.
a7
.
id
,
'id_plus_one'
:
self
.
a7
.
id
+
1
},
{
'id'
:
self
.
a7
.
id
,
'id_plus_one'
:
self
.
a7
.
id
+
1
},
{
'id'
:
self
.
a1
.
id
,
'id_plus_one'
:
self
.
a1
.
id
+
1
},
{
'id'
:
self
.
a1
.
id
,
'id_plus_one'
:
self
.
a1
.
id
+
1
},
],
],
transform
=
identity
)
transform
=
identity
)
data
=
{
data
=
{
'id_plus_one'
:
'id+1'
,
'id_plus_one'
:
'id+1'
,
'id_plus_two'
:
'id+2'
,
'id_plus_two'
:
'id+2'
,
...
@@ -217,7 +217,8 @@ class LookupTests(TestCase):
...
@@ -217,7 +217,8 @@ class LookupTests(TestCase):
'id_plus_six'
:
self
.
a1
.
id
+
6
,
'id_plus_six'
:
self
.
a1
.
id
+
6
,
'id_plus_seven'
:
self
.
a1
.
id
+
7
,
'id_plus_seven'
:
self
.
a1
.
id
+
7
,
'id_plus_eight'
:
self
.
a1
.
id
+
8
,
'id_plus_eight'
:
self
.
a1
.
id
+
8
,
}],
transform
=
identity
)
}],
transform
=
identity
)
# You can specify fields from forward and reverse relations, just like filter().
# You can specify fields from forward and reverse relations, just like filter().
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
Article
.
objects
.
values
(
'headline'
,
'author__name'
),
Article
.
objects
.
values
(
'headline'
,
'author__name'
),
...
@@ -229,7 +230,8 @@ class LookupTests(TestCase):
...
@@ -229,7 +230,8 @@ class LookupTests(TestCase):
{
'headline'
:
self
.
a3
.
headline
,
'author__name'
:
self
.
au1
.
name
},
{
'headline'
:
self
.
a3
.
headline
,
'author__name'
:
self
.
au1
.
name
},
{
'headline'
:
self
.
a7
.
headline
,
'author__name'
:
self
.
au2
.
name
},
{
'headline'
:
self
.
a7
.
headline
,
'author__name'
:
self
.
au2
.
name
},
{
'headline'
:
self
.
a1
.
headline
,
'author__name'
:
self
.
au1
.
name
},
{
'headline'
:
self
.
a1
.
headline
,
'author__name'
:
self
.
au1
.
name
},
],
transform
=
identity
)
],
transform
=
identity
)
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
Author
.
objects
.
values
(
'name'
,
'article__headline'
)
.
order_by
(
'name'
,
'article__headline'
),
Author
.
objects
.
values
(
'name'
,
'article__headline'
)
.
order_by
(
'name'
,
'article__headline'
),
[
[
...
@@ -240,7 +242,8 @@ class LookupTests(TestCase):
...
@@ -240,7 +242,8 @@ class LookupTests(TestCase):
{
'name'
:
self
.
au2
.
name
,
'article__headline'
:
self
.
a5
.
headline
},
{
'name'
:
self
.
au2
.
name
,
'article__headline'
:
self
.
a5
.
headline
},
{
'name'
:
self
.
au2
.
name
,
'article__headline'
:
self
.
a6
.
headline
},
{
'name'
:
self
.
au2
.
name
,
'article__headline'
:
self
.
a6
.
headline
},
{
'name'
:
self
.
au2
.
name
,
'article__headline'
:
self
.
a7
.
headline
},
{
'name'
:
self
.
au2
.
name
,
'article__headline'
:
self
.
a7
.
headline
},
],
transform
=
identity
)
],
transform
=
identity
)
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
(
(
Author
.
objects
Author
.
objects
...
@@ -257,20 +260,24 @@ class LookupTests(TestCase):
...
@@ -257,20 +260,24 @@ class LookupTests(TestCase):
{
'name'
:
self
.
au2
.
name
,
'article__headline'
:
self
.
a5
.
headline
,
'article__tag__name'
:
self
.
t3
.
name
},
{
'name'
:
self
.
au2
.
name
,
'article__headline'
:
self
.
a5
.
headline
,
'article__tag__name'
:
self
.
t3
.
name
},
{
'name'
:
self
.
au2
.
name
,
'article__headline'
:
self
.
a6
.
headline
,
'article__tag__name'
:
self
.
t3
.
name
},
{
'name'
:
self
.
au2
.
name
,
'article__headline'
:
self
.
a6
.
headline
,
'article__tag__name'
:
self
.
t3
.
name
},
{
'name'
:
self
.
au2
.
name
,
'article__headline'
:
self
.
a7
.
headline
,
'article__tag__name'
:
self
.
t3
.
name
},
{
'name'
:
self
.
au2
.
name
,
'article__headline'
:
self
.
a7
.
headline
,
'article__tag__name'
:
self
.
t3
.
name
},
],
transform
=
identity
)
],
transform
=
identity
)
# However, an exception FieldDoesNotExist will be thrown if you specify
# However, an exception FieldDoesNotExist will be thrown if you specify
# a non-existent field name in values() (a field that is neither in the
# a non-existent field name in values() (a field that is neither in the
# model nor in extra(select)).
# model nor in extra(select)).
with
self
.
assertRaises
(
FieldError
):
with
self
.
assertRaises
(
FieldError
):
Article
.
objects
.
extra
(
select
=
{
'id_plus_one'
:
'id + 1'
})
.
values
(
'id'
,
'id_plus_two'
)
Article
.
objects
.
extra
(
select
=
{
'id_plus_one'
:
'id + 1'
})
.
values
(
'id'
,
'id_plus_two'
)
# If you don't specify field names to values(), all are returned.
# If you don't specify field names to values(), all are returned.
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
id
=
self
.
a5
.
id
)
.
values
(),
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
id
=
self
.
a5
.
id
)
.
values
(),
[{
[{
'id'
:
self
.
a5
.
id
,
'id'
:
self
.
a5
.
id
,
'author_id'
:
self
.
au2
.
id
,
'author_id'
:
self
.
au2
.
id
,
'headline'
:
'Article 5'
,
'headline'
:
'Article 5'
,
'pub_date'
:
datetime
(
2005
,
8
,
1
,
9
,
0
)
'pub_date'
:
datetime
(
2005
,
8
,
1
,
9
,
0
)
}],
transform
=
identity
)
}],
transform
=
identity
)
def
test_values_list
(
self
):
def
test_values_list
(
self
):
# values_list() is similar to values(), except that the results are
# values_list() is similar to values(), except that the results are
...
@@ -279,7 +286,8 @@ class LookupTests(TestCase):
...
@@ -279,7 +286,8 @@ class LookupTests(TestCase):
# of fields in the values_list() call.
# of fields in the values_list() call.
def
identity
(
x
):
def
identity
(
x
):
return
x
return
x
self
.
assertQuerysetEqual
(
Article
.
objects
.
values_list
(
'headline'
),
self
.
assertQuerysetEqual
(
Article
.
objects
.
values_list
(
'headline'
),
[
[
(
'Article 5'
,),
(
'Article 5'
,),
(
'Article 6'
,),
(
'Article 6'
,),
...
@@ -288,22 +296,25 @@ class LookupTests(TestCase):
...
@@ -288,22 +296,25 @@ class LookupTests(TestCase):
(
'Article 3'
,),
(
'Article 3'
,),
(
'Article 7'
,),
(
'Article 7'
,),
(
'Article 1'
,),
(
'Article 1'
,),
],
transform
=
identity
)
],
transform
=
identity
self
.
assertQuerysetEqual
(
Article
.
objects
.
values_list
(
'id'
)
.
order_by
(
'id'
),
)
self
.
assertQuerysetEqual
(
Article
.
objects
.
values_list
(
'id'
)
.
order_by
(
'id'
),
[(
self
.
a1
.
id
,),
(
self
.
a2
.
id
,),
(
self
.
a3
.
id
,),
(
self
.
a4
.
id
,),
(
self
.
a5
.
id
,),
(
self
.
a6
.
id
,),
(
self
.
a7
.
id
,)],
[(
self
.
a1
.
id
,),
(
self
.
a2
.
id
,),
(
self
.
a3
.
id
,),
(
self
.
a4
.
id
,),
(
self
.
a5
.
id
,),
(
self
.
a6
.
id
,),
(
self
.
a7
.
id
,)],
transform
=
identity
)
transform
=
identity
)
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
Article
.
objects
.
values_list
(
'id'
,
flat
=
True
)
.
order_by
(
'id'
),
Article
.
objects
.
values_list
(
'id'
,
flat
=
True
)
.
order_by
(
'id'
),
[
self
.
a1
.
id
,
self
.
a2
.
id
,
self
.
a3
.
id
,
self
.
a4
.
id
,
self
.
a5
.
id
,
self
.
a6
.
id
,
self
.
a7
.
id
],
[
self
.
a1
.
id
,
self
.
a2
.
id
,
self
.
a3
.
id
,
self
.
a4
.
id
,
self
.
a5
.
id
,
self
.
a6
.
id
,
self
.
a7
.
id
],
transform
=
identity
)
transform
=
identity
)
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
Article
.
objects
.
extra
(
select
=
{
'id_plus_one'
:
'id+1'
})
Article
.
objects
.
extra
(
select
=
{
'id_plus_one'
:
'id+1'
})
.
order_by
(
'id'
)
.
values_list
(
'id'
),
.
order_by
(
'id'
)
.
values_list
(
'id'
),
[(
self
.
a1
.
id
,),
(
self
.
a2
.
id
,),
(
self
.
a3
.
id
,),
(
self
.
a4
.
id
,),
(
self
.
a5
.
id
,),
(
self
.
a6
.
id
,),
(
self
.
a7
.
id
,)],
[(
self
.
a1
.
id
,),
(
self
.
a2
.
id
,),
(
self
.
a3
.
id
,),
(
self
.
a4
.
id
,),
(
self
.
a5
.
id
,),
(
self
.
a6
.
id
,),
(
self
.
a7
.
id
,)],
transform
=
identity
)
transform
=
identity
)
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
Article
.
objects
.
extra
(
select
=
{
'id_plus_one'
:
'id+1'
})
Article
.
objects
.
extra
(
select
=
{
'id_plus_one'
:
'id+1'
})
.
order_by
(
'id'
)
.
values_list
(
'id_plus_one'
,
'id'
),
.
order_by
(
'id'
)
.
values_list
(
'id_plus_one'
,
'id'
),
[
[
(
self
.
a1
.
id
+
1
,
self
.
a1
.
id
),
(
self
.
a1
.
id
+
1
,
self
.
a1
.
id
),
(
self
.
a2
.
id
+
1
,
self
.
a2
.
id
),
(
self
.
a2
.
id
+
1
,
self
.
a2
.
id
),
...
@@ -313,10 +324,10 @@ class LookupTests(TestCase):
...
@@ -313,10 +324,10 @@ class LookupTests(TestCase):
(
self
.
a6
.
id
+
1
,
self
.
a6
.
id
),
(
self
.
a6
.
id
+
1
,
self
.
a6
.
id
),
(
self
.
a7
.
id
+
1
,
self
.
a7
.
id
)
(
self
.
a7
.
id
+
1
,
self
.
a7
.
id
)
],
],
transform
=
identity
)
transform
=
identity
)
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
Article
.
objects
.
extra
(
select
=
{
'id_plus_one'
:
'id+1'
})
Article
.
objects
.
extra
(
select
=
{
'id_plus_one'
:
'id+1'
})
.
order_by
(
'id'
)
.
values_list
(
'id'
,
'id_plus_one'
),
.
order_by
(
'id'
)
.
values_list
(
'id'
,
'id_plus_one'
),
[
[
(
self
.
a1
.
id
,
self
.
a1
.
id
+
1
),
(
self
.
a1
.
id
,
self
.
a1
.
id
+
1
),
(
self
.
a2
.
id
,
self
.
a2
.
id
+
1
),
(
self
.
a2
.
id
,
self
.
a2
.
id
+
1
),
...
@@ -326,13 +337,11 @@ class LookupTests(TestCase):
...
@@ -326,13 +337,11 @@ class LookupTests(TestCase):
(
self
.
a6
.
id
,
self
.
a6
.
id
+
1
),
(
self
.
a6
.
id
,
self
.
a6
.
id
+
1
),
(
self
.
a7
.
id
,
self
.
a7
.
id
+
1
)
(
self
.
a7
.
id
,
self
.
a7
.
id
+
1
)
],
],
transform
=
identity
)
transform
=
identity
)
args
=
(
'name'
,
'article__headline'
,
'article__tag__name'
)
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
(
Author
.
objects
.
values_list
(
*
args
)
.
order_by
(
*
args
),
Author
.
objects
.
values_list
(
'name'
,
'article__headline'
,
'article__tag__name'
)
.
order_by
(
'name'
,
'article__headline'
,
'article__tag__name'
)
),
[
[
(
self
.
au1
.
name
,
self
.
a1
.
headline
,
self
.
t1
.
name
),
(
self
.
au1
.
name
,
self
.
a1
.
headline
,
self
.
t1
.
name
),
(
self
.
au1
.
name
,
self
.
a2
.
headline
,
self
.
t1
.
name
),
(
self
.
au1
.
name
,
self
.
a2
.
headline
,
self
.
t1
.
name
),
...
@@ -343,7 +352,8 @@ class LookupTests(TestCase):
...
@@ -343,7 +352,8 @@ class LookupTests(TestCase):
(
self
.
au2
.
name
,
self
.
a5
.
headline
,
self
.
t3
.
name
),
(
self
.
au2
.
name
,
self
.
a5
.
headline
,
self
.
t3
.
name
),
(
self
.
au2
.
name
,
self
.
a6
.
headline
,
self
.
t3
.
name
),
(
self
.
au2
.
name
,
self
.
a6
.
headline
,
self
.
t3
.
name
),
(
self
.
au2
.
name
,
self
.
a7
.
headline
,
self
.
t3
.
name
),
(
self
.
au2
.
name
,
self
.
a7
.
headline
,
self
.
t3
.
name
),
],
transform
=
identity
)
],
transform
=
identity
)
with
self
.
assertRaises
(
TypeError
):
with
self
.
assertRaises
(
TypeError
):
Article
.
objects
.
values_list
(
'id'
,
'headline'
,
flat
=
True
)
Article
.
objects
.
values_list
(
'id'
,
'headline'
,
flat
=
True
)
...
@@ -352,42 +362,30 @@ class LookupTests(TestCase):
...
@@ -352,42 +362,30 @@ class LookupTests(TestCase):
# get_previous_by_FOO() methods. In the case of identical date values,
# get_previous_by_FOO() methods. In the case of identical date values,
# these methods will use the ID as a fallback check. This guarantees
# these methods will use the ID as a fallback check. This guarantees
# that no records are skipped or duplicated.
# that no records are skipped or duplicated.
self
.
assertEqual
(
repr
(
self
.
a1
.
get_next_by_pub_date
()),
self
.
assertEqual
(
repr
(
self
.
a1
.
get_next_by_pub_date
()),
'<Article: Article 2>'
)
'<Article: Article 2>'
)
self
.
assertEqual
(
repr
(
self
.
a2
.
get_next_by_pub_date
()),
'<Article: Article 3>'
)
self
.
assertEqual
(
repr
(
self
.
a2
.
get_next_by_pub_date
()),
self
.
assertEqual
(
repr
(
self
.
a2
.
get_next_by_pub_date
(
headline__endswith
=
'6'
)),
'<Article: Article 6>'
)
'<Article: Article 3>'
)
self
.
assertEqual
(
repr
(
self
.
a3
.
get_next_by_pub_date
()),
'<Article: Article 7>'
)
self
.
assertEqual
(
repr
(
self
.
a2
.
get_next_by_pub_date
(
headline__endswith
=
'6'
)),
self
.
assertEqual
(
repr
(
self
.
a4
.
get_next_by_pub_date
()),
'<Article: Article 6>'
)
'<Article: Article 6>'
)
self
.
assertEqual
(
repr
(
self
.
a3
.
get_next_by_pub_date
()),
'<Article: Article 7>'
)
self
.
assertEqual
(
repr
(
self
.
a4
.
get_next_by_pub_date
()),
'<Article: Article 6>'
)
with
self
.
assertRaises
(
Article
.
DoesNotExist
):
with
self
.
assertRaises
(
Article
.
DoesNotExist
):
self
.
a5
.
get_next_by_pub_date
()
self
.
a5
.
get_next_by_pub_date
()
self
.
assertEqual
(
repr
(
self
.
a6
.
get_next_by_pub_date
()),
self
.
assertEqual
(
repr
(
self
.
a6
.
get_next_by_pub_date
()),
'<Article: Article 5>'
)
'<Article: Article 5>'
)
self
.
assertEqual
(
repr
(
self
.
a7
.
get_next_by_pub_date
()),
'<Article: Article 4>'
)
self
.
assertEqual
(
repr
(
self
.
a7
.
get_next_by_pub_date
()),
'<Article: Article 4>'
)
self
.
assertEqual
(
repr
(
self
.
a7
.
get_previous_by_pub_date
()),
'<Article: Article 3>'
)
self
.
assertEqual
(
repr
(
self
.
a6
.
get_previous_by_pub_date
()),
'<Article: Article 4>'
)
self
.
assertEqual
(
repr
(
self
.
a7
.
get_previous_by_pub_date
()),
self
.
assertEqual
(
repr
(
self
.
a5
.
get_previous_by_pub_date
()),
'<Article: Article 6>'
)
'<Article: Article 3>'
)
self
.
assertEqual
(
repr
(
self
.
a4
.
get_previous_by_pub_date
()),
'<Article: Article 7>'
)
self
.
assertEqual
(
repr
(
self
.
a6
.
get_previous_by_pub_date
()),
self
.
assertEqual
(
repr
(
self
.
a3
.
get_previous_by_pub_date
()),
'<Article: Article 2>'
)
'<Article: Article 4>'
)
self
.
assertEqual
(
repr
(
self
.
a2
.
get_previous_by_pub_date
()),
'<Article: Article 1>'
)
self
.
assertEqual
(
repr
(
self
.
a5
.
get_previous_by_pub_date
()),
'<Article: Article 6>'
)
self
.
assertEqual
(
repr
(
self
.
a4
.
get_previous_by_pub_date
()),
'<Article: Article 7>'
)
self
.
assertEqual
(
repr
(
self
.
a3
.
get_previous_by_pub_date
()),
'<Article: Article 2>'
)
self
.
assertEqual
(
repr
(
self
.
a2
.
get_previous_by_pub_date
()),
'<Article: Article 1>'
)
def
test_escaping
(
self
):
def
test_escaping
(
self
):
# Underscores, percent signs and backslashes have special meaning in the
# Underscores, percent signs and backslashes have special meaning in the
# underlying SQL code, but Django handles the quoting of them automatically.
# underlying SQL code, but Django handles the quoting of them automatically.
a8
=
Article
(
headline
=
'Article_ with underscore'
,
pub_date
=
datetime
(
2005
,
11
,
20
))
Article
.
objects
.
create
(
headline
=
'Article_ with underscore'
,
pub_date
=
datetime
(
2005
,
11
,
20
))
a8
.
save
()
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__startswith
=
'Article'
),
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__startswith
=
'Article'
),
[
[
'<Article: Article_ with underscore>'
,
'<Article: Article_ with underscore>'
,
'<Article: Article 5>'
,
'<Article: Article 5>'
,
...
@@ -397,12 +395,15 @@ class LookupTests(TestCase):
...
@@ -397,12 +395,15 @@ class LookupTests(TestCase):
'<Article: Article 3>'
,
'<Article: Article 3>'
,
'<Article: Article 7>'
,
'<Article: Article 7>'
,
'<Article: Article 1>'
,
'<Article: Article 1>'
,
])
]
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__startswith
=
'Article_'
),
)
[
'<Article: Article_ with underscore>'
])
self
.
assertQuerysetEqual
(
a9
=
Article
(
headline
=
'Article
%
with percent sign'
,
pub_date
=
datetime
(
2005
,
11
,
21
))
Article
.
objects
.
filter
(
headline__startswith
=
'Article_'
),
a9
.
save
()
[
'<Article: Article_ with underscore>'
]
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__startswith
=
'Article'
),
)
Article
.
objects
.
create
(
headline
=
'Article
%
with percent sign'
,
pub_date
=
datetime
(
2005
,
11
,
21
))
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__startswith
=
'Article'
),
[
[
'<Article: Article
%
with percent sign>'
,
'<Article: Article
%
with percent sign>'
,
'<Article: Article_ with underscore>'
,
'<Article: Article_ with underscore>'
,
...
@@ -413,13 +414,17 @@ class LookupTests(TestCase):
...
@@ -413,13 +414,17 @@ class LookupTests(TestCase):
'<Article: Article 3>'
,
'<Article: Article 3>'
,
'<Article: Article 7>'
,
'<Article: Article 7>'
,
'<Article: Article 1>'
,
'<Article: Article 1>'
,
])
]
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__startswith
=
'Article
%
'
),
)
[
'<Article: Article
%
with percent sign>'
])
self
.
assertQuerysetEqual
(
a10
=
Article
(
headline
=
'Article with
\\
backslash'
,
pub_date
=
datetime
(
2005
,
11
,
22
))
Article
.
objects
.
filter
(
headline__startswith
=
'Article
%
'
),
a10
.
save
()
[
'<Article: Article
%
with percent sign>'
]
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__contains
=
'
\\
'
),
)
[
'<Article: Article with
\
backslash>'
])
Article
.
objects
.
create
(
headline
=
'Article with
\\
backslash'
,
pub_date
=
datetime
(
2005
,
11
,
22
))
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__contains
=
'
\\
'
),
[
'<Article: Article with
\
backslash>'
]
)
def
test_exclude
(
self
):
def
test_exclude
(
self
):
Article
.
objects
.
create
(
headline
=
'Article_ with underscore'
,
pub_date
=
datetime
(
2005
,
11
,
20
))
Article
.
objects
.
create
(
headline
=
'Article_ with underscore'
,
pub_date
=
datetime
(
2005
,
11
,
20
))
...
@@ -437,8 +442,10 @@ class LookupTests(TestCase):
...
@@ -437,8 +442,10 @@ class LookupTests(TestCase):
'<Article: Article 3>'
,
'<Article: Article 3>'
,
'<Article: Article 7>'
,
'<Article: Article 7>'
,
'<Article: Article 1>'
,
'<Article: Article 1>'
,
])
]
self
.
assertQuerysetEqual
(
Article
.
objects
.
exclude
(
headline__startswith
=
"Article_"
),
)
self
.
assertQuerysetEqual
(
Article
.
objects
.
exclude
(
headline__startswith
=
"Article_"
),
[
[
'<Article: Article with
\\
backslash>'
,
'<Article: Article with
\\
backslash>'
,
'<Article: Article
%
with percent sign>'
,
'<Article: Article
%
with percent sign>'
,
...
@@ -449,8 +456,10 @@ class LookupTests(TestCase):
...
@@ -449,8 +456,10 @@ class LookupTests(TestCase):
'<Article: Article 3>'
,
'<Article: Article 3>'
,
'<Article: Article 7>'
,
'<Article: Article 7>'
,
'<Article: Article 1>'
,
'<Article: Article 1>'
,
])
]
self
.
assertQuerysetEqual
(
Article
.
objects
.
exclude
(
headline
=
"Article 7"
),
)
self
.
assertQuerysetEqual
(
Article
.
objects
.
exclude
(
headline
=
"Article 7"
),
[
[
'<Article: Article with
\\
backslash>'
,
'<Article: Article with
\\
backslash>'
,
'<Article: Article
%
with percent sign>'
,
'<Article: Article
%
with percent sign>'
,
...
@@ -461,26 +470,23 @@ class LookupTests(TestCase):
...
@@ -461,26 +470,23 @@ class LookupTests(TestCase):
'<Article: Article 2>'
,
'<Article: Article 2>'
,
'<Article: Article 3>'
,
'<Article: Article 3>'
,
'<Article: Article 1>'
,
'<Article: Article 1>'
,
])
]
)
def
test_none
(
self
):
def
test_none
(
self
):
# none() returns a QuerySet that behaves like any other QuerySet object
# none() returns a QuerySet that behaves like any other QuerySet object
self
.
assertQuerysetEqual
(
Article
.
objects
.
none
(),
[])
self
.
assertQuerysetEqual
(
Article
.
objects
.
none
(),
[])
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
Article
.
objects
.
none
()
.
filter
(
headline__startswith
=
'Article'
),
[])
Article
.
objects
.
none
()
.
filter
(
headline__startswith
=
'Article'
),
[])
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__startswith
=
'Article'
)
.
none
(),
[])
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__startswith
=
'Article'
)
.
none
(),
[])
self
.
assertEqual
(
Article
.
objects
.
none
()
.
count
(),
0
)
self
.
assertEqual
(
Article
.
objects
.
none
()
.
count
(),
0
)
self
.
assertEqual
(
self
.
assertEqual
(
Article
.
objects
.
none
()
.
update
(
headline
=
"This should not take effect"
),
0
)
Article
.
objects
.
none
()
.
update
(
headline
=
"This should not take effect"
),
0
)
self
.
assertQuerysetEqual
([
article
for
article
in
Article
.
objects
.
none
()
.
iterator
()],
[])
self
.
assertQuerysetEqual
(
[
article
for
article
in
Article
.
objects
.
none
()
.
iterator
()],
[])
def
test_in
(
self
):
def
test_in
(
self
):
# using __in with an empty list should return an empty query set
# using __in with an empty list should return an empty query set
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
id__in
=
[]),
[])
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
id__in
=
[]),
[])
self
.
assertQuerysetEqual
(
Article
.
objects
.
exclude
(
id__in
=
[]),
self
.
assertQuerysetEqual
(
Article
.
objects
.
exclude
(
id__in
=
[]),
[
[
'<Article: Article 5>'
,
'<Article: Article 5>'
,
'<Article: Article 6>'
,
'<Article: Article 6>'
,
...
@@ -489,24 +495,24 @@ class LookupTests(TestCase):
...
@@ -489,24 +495,24 @@ class LookupTests(TestCase):
'<Article: Article 3>'
,
'<Article: Article 3>'
,
'<Article: Article 7>'
,
'<Article: Article 7>'
,
'<Article: Article 1>'
,
'<Article: Article 1>'
,
])
]
)
def
test_error_messages
(
self
):
def
test_error_messages
(
self
):
# Programming errors are pointed out with nice error messages
# Programming errors are pointed out with nice error messages
try
:
with
self
.
assertRaisesMessage
(
FieldError
,
"Cannot resolve keyword 'pub_date_year' into field. Choices are: "
"author, author_id, headline, id, pub_date, tag"
):
Article
.
objects
.
filter
(
pub_date_year
=
'2005'
)
.
count
()
Article
.
objects
.
filter
(
pub_date_year
=
'2005'
)
.
count
()
self
.
fail
(
'FieldError not raised'
)
except
FieldError
as
ex
:
with
self
.
assertRaisesMessage
(
self
.
assertEqual
(
str
(
ex
),
"Cannot resolve keyword 'pub_date_year' "
FieldError
,
"into field. Choices are: author, author_id, headline,
"
"Unsupported lookup 'starts' for CharField or join on the field
"
"id, pub_date, tag"
)
"not permitted."
try
:
)
:
Article
.
objects
.
filter
(
headline__starts
=
'Article'
)
Article
.
objects
.
filter
(
headline__starts
=
'Article'
)
self
.
fail
(
'FieldError not raised'
)
except
FieldError
as
ex
:
self
.
assertEqual
(
str
(
ex
),
"Unsupported lookup 'starts' for CharField "
"or join on the field not permitted."
)
def
test_relation_nested_lookup_error
(
self
):
def
test_relation_nested_lookup_error
(
self
):
# An invalid nested lookup on a related field raises a useful error.
# An invalid nested lookup on a related field raises a useful error.
...
@@ -519,132 +525,134 @@ class LookupTests(TestCase):
...
@@ -519,132 +525,134 @@ class LookupTests(TestCase):
for
a
in
Article
.
objects
.
all
():
for
a
in
Article
.
objects
.
all
():
a
.
delete
()
a
.
delete
()
now
=
datetime
.
now
()
now
=
datetime
.
now
()
a1
=
Article
(
pub_date
=
now
,
headline
=
'f'
)
Article
.
objects
.
create
(
pub_date
=
now
,
headline
=
'f'
)
a1
.
save
()
Article
.
objects
.
create
(
pub_date
=
now
,
headline
=
'fo'
)
a2
=
Article
(
pub_date
=
now
,
headline
=
'fo'
)
Article
.
objects
.
create
(
pub_date
=
now
,
headline
=
'foo'
)
a2
.
save
()
Article
.
objects
.
create
(
pub_date
=
now
,
headline
=
'fooo'
)
a3
=
Article
(
pub_date
=
now
,
headline
=
'foo'
)
Article
.
objects
.
create
(
pub_date
=
now
,
headline
=
'hey-Foo'
)
a3
.
save
()
Article
.
objects
.
create
(
pub_date
=
now
,
headline
=
'bar'
)
a4
=
Article
(
pub_date
=
now
,
headline
=
'fooo'
)
Article
.
objects
.
create
(
pub_date
=
now
,
headline
=
'AbBa'
)
a4
.
save
()
Article
.
objects
.
create
(
pub_date
=
now
,
headline
=
'baz'
)
a5
=
Article
(
pub_date
=
now
,
headline
=
'hey-Foo'
)
Article
.
objects
.
create
(
pub_date
=
now
,
headline
=
'baxZ'
)
a5
.
save
()
a6
=
Article
(
pub_date
=
now
,
headline
=
'bar'
)
a6
.
save
()
a7
=
Article
(
pub_date
=
now
,
headline
=
'AbBa'
)
a7
.
save
()
a8
=
Article
(
pub_date
=
now
,
headline
=
'baz'
)
a8
.
save
()
a9
=
Article
(
pub_date
=
now
,
headline
=
'baxZ'
)
a9
.
save
()
# zero-or-more
# zero-or-more
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__regex
=
r'fo*'
),
self
.
assertQuerysetEqual
(
[
'<Article: f>'
,
'<Article: fo>'
,
'<Article: foo>'
,
'<Article: fooo>'
])
Article
.
objects
.
filter
(
headline__regex
=
r'fo*'
),
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__iregex
=
r'fo*'
),
[
'<Article: f>'
,
'<Article: fo>'
,
'<Article: foo>'
,
'<Article: fooo>'
]
)
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__iregex
=
r'fo*'
),
[
[
'<Article: f>'
,
'<Article: f>'
,
'<Article: fo>'
,
'<Article: fo>'
,
'<Article: foo>'
,
'<Article: foo>'
,
'<Article: fooo>'
,
'<Article: fooo>'
,
'<Article: hey-Foo>'
,
'<Article: hey-Foo>'
,
])
]
)
# one-or-more
# one-or-more
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__regex
=
r'fo+'
),
self
.
assertQuerysetEqual
(
[
'<Article: fo>'
,
'<Article: foo>'
,
'<Article: fooo>'
])
Article
.
objects
.
filter
(
headline__regex
=
r'fo+'
),
[
'<Article: fo>'
,
'<Article: foo>'
,
'<Article: fooo>'
]
)
# wildcard
# wildcard
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__regex
=
r'fooo?'
),
self
.
assertQuerysetEqual
(
[
'<Article: foo>'
,
'<Article: fooo>'
])
Article
.
objects
.
filter
(
headline__regex
=
r'fooo?'
),
[
'<Article: foo>'
,
'<Article: fooo>'
]
)
# leading anchor
# leading anchor
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__regex
=
r'^b'
),
self
.
assertQuerysetEqual
(
[
'<Article: bar>'
,
'<Article: baxZ>'
,
'<Article: baz>'
])
Article
.
objects
.
filter
(
headline__regex
=
r'^b'
),
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__iregex
=
r'^a'
),
[
'<Article: bar>'
,
'<Article: baxZ>'
,
'<Article: baz>'
]
[
'<Article: AbBa>'
])
)
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__iregex
=
r'^a'
),
[
'<Article: AbBa>'
])
# trailing anchor
# trailing anchor
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__regex
=
r'z$'
),
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__regex
=
r'z$'
),
[
'<Article: baz>'
])
[
'<Article: baz>'
])
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__iregex
=
r'z$'
),
Article
.
objects
.
filter
(
headline__iregex
=
r'z$'
),
[
'<Article: baxZ>'
,
'<Article: baz>'
])
[
'<Article: baxZ>'
,
'<Article: baz>'
]
)
# character sets
# character sets
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__regex
=
r'ba[rz]'
),
self
.
assertQuerysetEqual
(
[
'<Article: bar>'
,
'<Article: baz>'
])
Article
.
objects
.
filter
(
headline__regex
=
r'ba[rz]'
),
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__regex
=
r'ba.[RxZ]'
),
[
'<Article: bar>'
,
'<Article: baz>'
]
[
'<Article: baxZ>'
])
)
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__iregex
=
r'ba[RxZ]'
),
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__regex
=
r'ba.[RxZ]'
),
[
'<Article: baxZ>'
])
[
'<Article: bar>'
,
'<Article: baxZ>'
,
'<Article: baz>'
])
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__iregex
=
r'ba[RxZ]'
),
[
'<Article: bar>'
,
'<Article: baxZ>'
,
'<Article: baz>'
]
)
# and more articles:
# and more articles:
a10
=
Article
(
pub_date
=
now
,
headline
=
'foobar'
)
Article
.
objects
.
create
(
pub_date
=
now
,
headline
=
'foobar'
)
a10
.
save
()
Article
.
objects
.
create
(
pub_date
=
now
,
headline
=
'foobaz'
)
a11
=
Article
(
pub_date
=
now
,
headline
=
'foobaz'
)
Article
.
objects
.
create
(
pub_date
=
now
,
headline
=
'ooF'
)
a11
.
save
()
Article
.
objects
.
create
(
pub_date
=
now
,
headline
=
'foobarbaz'
)
a12
=
Article
(
pub_date
=
now
,
headline
=
'ooF'
)
Article
.
objects
.
create
(
pub_date
=
now
,
headline
=
'zoocarfaz'
)
a12
.
save
()
Article
.
objects
.
create
(
pub_date
=
now
,
headline
=
'barfoobaz'
)
a13
=
Article
(
pub_date
=
now
,
headline
=
'foobarbaz'
)
Article
.
objects
.
create
(
pub_date
=
now
,
headline
=
'bazbaRFOO'
)
a13
.
save
()
a14
=
Article
(
pub_date
=
now
,
headline
=
'zoocarfaz'
)
a14
.
save
()
a15
=
Article
(
pub_date
=
now
,
headline
=
'barfoobaz'
)
a15
.
save
()
a16
=
Article
(
pub_date
=
now
,
headline
=
'bazbaRFOO'
)
a16
.
save
()
# alternation
# alternation
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__regex
=
r'oo(f|b)'
),
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__regex
=
r'oo(f|b)'
),
[
[
'<Article: barfoobaz>'
,
'<Article: barfoobaz>'
,
'<Article: foobar>'
,
'<Article: foobar>'
,
'<Article: foobarbaz>'
,
'<Article: foobarbaz>'
,
'<Article: foobaz>'
,
'<Article: foobaz>'
,
])
]
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__iregex
=
r'oo(f|b)'
),
)
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__iregex
=
r'oo(f|b)'
),
[
[
'<Article: barfoobaz>'
,
'<Article: barfoobaz>'
,
'<Article: foobar>'
,
'<Article: foobar>'
,
'<Article: foobarbaz>'
,
'<Article: foobarbaz>'
,
'<Article: foobaz>'
,
'<Article: foobaz>'
,
'<Article: ooF>'
,
'<Article: ooF>'
,
])
]
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__regex
=
r'^foo(f|b)'
),
)
[
'<Article: foobar>'
,
'<Article: foobarbaz>'
,
'<Article: foobaz>'
])
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__regex
=
r'^foo(f|b)'
),
[
'<Article: foobar>'
,
'<Article: foobarbaz>'
,
'<Article: foobaz>'
]
)
# greedy matching
# greedy matching
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__regex
=
r'b.*az'
),
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__regex
=
r'b.*az'
),
[
[
'<Article: barfoobaz>'
,
'<Article: barfoobaz>'
,
'<Article: baz>'
,
'<Article: baz>'
,
'<Article: bazbaRFOO>'
,
'<Article: bazbaRFOO>'
,
'<Article: foobarbaz>'
,
'<Article: foobarbaz>'
,
'<Article: foobaz>'
,
'<Article: foobaz>'
,
])
]
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__iregex
=
r'b.*ar'
),
)
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__iregex
=
r'b.*ar'
),
[
[
'<Article: bar>'
,
'<Article: bar>'
,
'<Article: barfoobaz>'
,
'<Article: barfoobaz>'
,
'<Article: bazbaRFOO>'
,
'<Article: bazbaRFOO>'
,
'<Article: foobar>'
,
'<Article: foobar>'
,
'<Article: foobarbaz>'
,
'<Article: foobarbaz>'
,
])
]
)
@skipUnlessDBFeature
(
'supports_regex_backreferencing'
)
@skipUnlessDBFeature
(
'supports_regex_backreferencing'
)
def
test_regex_backreferencing
(
self
):
def
test_regex_backreferencing
(
self
):
# grouping and backreferences
# grouping and backreferences
now
=
datetime
.
now
()
now
=
datetime
.
now
()
a10
=
Article
(
pub_date
=
now
,
headline
=
'foobar'
)
Article
.
objects
.
create
(
pub_date
=
now
,
headline
=
'foobar'
)
a10
.
save
()
Article
.
objects
.
create
(
pub_date
=
now
,
headline
=
'foobaz'
)
a11
=
Article
(
pub_date
=
now
,
headline
=
'foobaz'
)
Article
.
objects
.
create
(
pub_date
=
now
,
headline
=
'ooF'
)
a11
.
save
()
Article
.
objects
.
create
(
pub_date
=
now
,
headline
=
'foobarbaz'
)
a12
=
Article
(
pub_date
=
now
,
headline
=
'ooF'
)
Article
.
objects
.
create
(
pub_date
=
now
,
headline
=
'zoocarfaz'
)
a12
.
save
()
Article
.
objects
.
create
(
pub_date
=
now
,
headline
=
'barfoobaz'
)
a13
=
Article
(
pub_date
=
now
,
headline
=
'foobarbaz'
)
Article
.
objects
.
create
(
pub_date
=
now
,
headline
=
'bazbaRFOO'
)
a13
.
save
()
self
.
assertQuerysetEqual
(
a14
=
Article
(
pub_date
=
now
,
headline
=
'zoocarfaz'
)
Article
.
objects
.
filter
(
headline__regex
=
r'b(.).*b\1'
),
a14
.
save
()
[
'<Article: barfoobaz>'
,
'<Article: bazbaRFOO>'
,
'<Article: foobarbaz>'
]
a15
=
Article
(
pub_date
=
now
,
headline
=
'barfoobaz'
)
)
a15
.
save
()
a16
=
Article
(
pub_date
=
now
,
headline
=
'bazbaRFOO'
)
a16
.
save
()
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__regex
=
r'b(.).*b\1'
),
[
'<Article: barfoobaz>'
,
'<Article: bazbaRFOO>'
,
'<Article: foobarbaz>'
])
def
test_regex_null
(
self
):
def
test_regex_null
(
self
):
"""
"""
...
@@ -658,8 +666,7 @@ class LookupTests(TestCase):
...
@@ -658,8 +666,7 @@ class LookupTests(TestCase):
Ensure that a regex lookup does not fail on non-string fields
Ensure that a regex lookup does not fail on non-string fields
"""
"""
Season
.
objects
.
create
(
year
=
2013
,
gt
=
444
)
Season
.
objects
.
create
(
year
=
2013
,
gt
=
444
)
self
.
assertQuerysetEqual
(
Season
.
objects
.
filter
(
gt__regex
=
r'^444$'
),
self
.
assertQuerysetEqual
(
Season
.
objects
.
filter
(
gt__regex
=
r'^444$'
),
[
'<Season: 2013>'
])
[
'<Season: 2013>'
])
def
test_regex_non_ascii
(
self
):
def
test_regex_non_ascii
(
self
):
"""
"""
...
...
tests/many_to_many/tests.py
Dosyayı görüntüle @
406675b1
...
@@ -2,7 +2,6 @@ from __future__ import unicode_literals
...
@@ -2,7 +2,6 @@ from __future__ import unicode_literals
from
django.db
import
transaction
from
django.db
import
transaction
from
django.test
import
TestCase
,
ignore_warnings
from
django.test
import
TestCase
,
ignore_warnings
from
django.utils
import
six
from
django.utils.deprecation
import
RemovedInDjango20Warning
from
django.utils.deprecation
import
RemovedInDjango20Warning
from
.models
import
Article
,
InheritedArticleA
,
InheritedArticleB
,
Publication
from
.models
import
Article
,
InheritedArticleA
,
InheritedArticleB
,
Publication
...
@@ -12,15 +11,15 @@ class ManyToManyTests(TestCase):
...
@@ -12,15 +11,15 @@ class ManyToManyTests(TestCase):
def
setUp
(
self
):
def
setUp
(
self
):
# Create a couple of Publications.
# Create a couple of Publications.
self
.
p1
=
Publication
.
objects
.
create
(
id
=
None
,
title
=
'The Python Journal'
)
self
.
p1
=
Publication
.
objects
.
create
(
title
=
'The Python Journal'
)
self
.
p2
=
Publication
.
objects
.
create
(
id
=
None
,
title
=
'Science News'
)
self
.
p2
=
Publication
.
objects
.
create
(
title
=
'Science News'
)
self
.
p3
=
Publication
.
objects
.
create
(
id
=
None
,
title
=
'Science Weekly'
)
self
.
p3
=
Publication
.
objects
.
create
(
title
=
'Science Weekly'
)
self
.
p4
=
Publication
.
objects
.
create
(
title
=
'Highlights for Children'
)
self
.
p4
=
Publication
.
objects
.
create
(
title
=
'Highlights for Children'
)
self
.
a1
=
Article
.
objects
.
create
(
id
=
None
,
headline
=
'Django lets you build Web apps easily'
)
self
.
a1
=
Article
.
objects
.
create
(
headline
=
'Django lets you build Web apps easily'
)
self
.
a1
.
publications
.
add
(
self
.
p1
)
self
.
a1
.
publications
.
add
(
self
.
p1
)
self
.
a2
=
Article
.
objects
.
create
(
id
=
None
,
headline
=
'NASA uses Python'
)
self
.
a2
=
Article
.
objects
.
create
(
headline
=
'NASA uses Python'
)
self
.
a2
.
publications
.
add
(
self
.
p1
,
self
.
p2
,
self
.
p3
,
self
.
p4
)
self
.
a2
.
publications
.
add
(
self
.
p1
,
self
.
p2
,
self
.
p3
,
self
.
p4
)
self
.
a3
=
Article
.
objects
.
create
(
headline
=
'NASA finds intelligent life on Earth'
)
self
.
a3
=
Article
.
objects
.
create
(
headline
=
'NASA finds intelligent life on Earth'
)
...
@@ -31,7 +30,7 @@ class ManyToManyTests(TestCase):
...
@@ -31,7 +30,7 @@ class ManyToManyTests(TestCase):
def
test_add
(
self
):
def
test_add
(
self
):
# Create an Article.
# Create an Article.
a5
=
Article
(
id
=
None
,
headline
=
'Django lets you reate Web apps easily'
)
a5
=
Article
(
headline
=
'Django lets you reate Web apps easily'
)
# You can't associate it with a Publication until it's been saved.
# You can't associate it with a Publication until it's been saved.
with
self
.
assertRaises
(
ValueError
):
with
self
.
assertRaises
(
ValueError
):
getattr
(
a5
,
'publications'
)
getattr
(
a5
,
'publications'
)
...
@@ -39,51 +38,55 @@ class ManyToManyTests(TestCase):
...
@@ -39,51 +38,55 @@ class ManyToManyTests(TestCase):
a5
.
save
()
a5
.
save
()
# Associate the Article with a Publication.
# Associate the Article with a Publication.
a5
.
publications
.
add
(
self
.
p1
)
a5
.
publications
.
add
(
self
.
p1
)
self
.
assertQuerysetEqual
(
a5
.
publications
.
all
(),
self
.
assertQuerysetEqual
(
a5
.
publications
.
all
(),
[
'<Publication: The Python Journal>'
])
[
'<Publication: The Python Journal>'
])
# Create another Article, and set it to appear in both Publications.
# Create another Article, and set it to appear in both Publications.
a6
=
Article
(
id
=
None
,
headline
=
'ESA uses Python'
)
a6
=
Article
(
headline
=
'ESA uses Python'
)
a6
.
save
()
a6
.
save
()
a6
.
publications
.
add
(
self
.
p1
,
self
.
p2
)
a6
.
publications
.
add
(
self
.
p1
,
self
.
p2
)
a6
.
publications
.
add
(
self
.
p3
)
a6
.
publications
.
add
(
self
.
p3
)
# Adding a second time is OK
# Adding a second time is OK
a6
.
publications
.
add
(
self
.
p3
)
a6
.
publications
.
add
(
self
.
p3
)
self
.
assertQuerysetEqual
(
a6
.
publications
.
all
(),
self
.
assertQuerysetEqual
(
a6
.
publications
.
all
(),
[
[
'<Publication: Science News>'
,
'<Publication: Science News>'
,
'<Publication: Science Weekly>'
,
'<Publication: Science Weekly>'
,
'<Publication: The Python Journal>'
,
'<Publication: The Python Journal>'
,
])
]
)
# Adding an object of the wrong type raises TypeError
# Adding an object of the wrong type raises TypeError
with
s
ix
.
assertRaisesRegex
(
self
,
TypeError
,
"'Publication' instance expected, got <Article.*
"
):
with
s
elf
.
assertRaisesMessage
(
TypeError
,
"'Publication' instance expected, got <Article
"
):
with
transaction
.
atomic
():
with
transaction
.
atomic
():
a6
.
publications
.
add
(
a5
)
a6
.
publications
.
add
(
a5
)
# Add a Publication directly via publications.add by using keyword arguments.
# Add a Publication directly via publications.add by using keyword arguments.
a6
.
publications
.
create
(
title
=
'Highlights for Adults'
)
a6
.
publications
.
create
(
title
=
'Highlights for Adults'
)
self
.
assertQuerysetEqual
(
a6
.
publications
.
all
(),
self
.
assertQuerysetEqual
(
a6
.
publications
.
all
(),
[
[
'<Publication: Highlights for Adults>'
,
'<Publication: Highlights for Adults>'
,
'<Publication: Science News>'
,
'<Publication: Science News>'
,
'<Publication: Science Weekly>'
,
'<Publication: Science Weekly>'
,
'<Publication: The Python Journal>'
,
'<Publication: The Python Journal>'
,
])
]
)
def
test_reverse_add
(
self
):
def
test_reverse_add
(
self
):
# Adding via the 'other' end of an m2m
# Adding via the 'other' end of an m2m
a5
=
Article
(
headline
=
'NASA finds intelligent life on Mars'
)
a5
=
Article
(
headline
=
'NASA finds intelligent life on Mars'
)
a5
.
save
()
a5
.
save
()
self
.
p2
.
article_set
.
add
(
a5
)
self
.
p2
.
article_set
.
add
(
a5
)
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
[
[
'<Article: NASA finds intelligent life on Earth>'
,
'<Article: NASA finds intelligent life on Earth>'
,
'<Article: NASA finds intelligent life on Mars>'
,
'<Article: NASA finds intelligent life on Mars>'
,
'<Article: NASA uses Python>'
,
'<Article: NASA uses Python>'
,
'<Article: Oxygen-free diet works wonders>'
,
'<Article: Oxygen-free diet works wonders>'
,
]
)
]
self
.
assertQuerysetEqual
(
a5
.
publications
.
all
(),
)
[
'<Publication: Science News>'
])
self
.
assertQuerysetEqual
(
a5
.
publications
.
all
(),
[
'<Publication: Science News>'
])
# Adding via the other end using keywords
# Adding via the other end using keywords
self
.
p2
.
article_set
.
create
(
headline
=
'Carbon-free diet works wonders'
)
self
.
p2
.
article_set
.
create
(
headline
=
'Carbon-free diet works wonders'
)
...
@@ -97,39 +100,48 @@ class ManyToManyTests(TestCase):
...
@@ -97,39 +100,48 @@ class ManyToManyTests(TestCase):
'<Article: Oxygen-free diet works wonders>'
,
'<Article: Oxygen-free diet works wonders>'
,
])
])
a6
=
self
.
p2
.
article_set
.
all
()[
3
]
a6
=
self
.
p2
.
article_set
.
all
()[
3
]
self
.
assertQuerysetEqual
(
a6
.
publications
.
all
(),
self
.
assertQuerysetEqual
(
a6
.
publications
.
all
(),
[
[
'<Publication: Highlights for Children>'
,
'<Publication: Highlights for Children>'
,
'<Publication: Science News>'
,
'<Publication: Science News>'
,
'<Publication: Science Weekly>'
,
'<Publication: Science Weekly>'
,
'<Publication: The Python Journal>'
,
'<Publication: The Python Journal>'
,
])
]
)
def
test_related_sets
(
self
):
def
test_related_sets
(
self
):
# Article objects have access to their related Publication objects.
# Article objects have access to their related Publication objects.
self
.
assertQuerysetEqual
(
self
.
a1
.
publications
.
all
(),
self
.
assertQuerysetEqual
(
self
.
a1
.
publications
.
all
(),
[
'<Publication: The Python Journal>'
])
[
'<Publication: The Python Journal>'
])
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
self
.
a2
.
publications
.
all
(),
self
.
a2
.
publications
.
all
(),
[
[
'<Publication: Highlights for Children>'
,
'<Publication: Highlights for Children>'
,
'<Publication: Science News>'
,
'<Publication: Science News>'
,
'<Publication: Science Weekly>'
,
'<Publication: Science Weekly>'
,
'<Publication: The Python Journal>'
,
'<Publication: The Python Journal>'
,
])
]
)
# Publication objects have access to their related Article objects.
# Publication objects have access to their related Article objects.
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
[
[
'<Article: NASA finds intelligent life on Earth>'
,
'<Article: NASA finds intelligent life on Earth>'
,
'<Article: NASA uses Python>'
,
'<Article: NASA uses Python>'
,
'<Article: Oxygen-free diet works wonders>'
,
'<Article: Oxygen-free diet works wonders>'
,
])
]
self
.
assertQuerysetEqual
(
self
.
p1
.
article_set
.
all
(),
)
self
.
assertQuerysetEqual
(
self
.
p1
.
article_set
.
all
(),
[
[
'<Article: Django lets you build Web apps easily>'
,
'<Article: Django lets you build Web apps easily>'
,
'<Article: NASA uses Python>'
,
'<Article: NASA uses Python>'
,
])
]
self
.
assertQuerysetEqual
(
Publication
.
objects
.
get
(
id
=
self
.
p4
.
id
)
.
article_set
.
all
(),
)
[
'<Article: NASA uses Python>'
])
self
.
assertQuerysetEqual
(
Publication
.
objects
.
get
(
id
=
self
.
p4
.
id
)
.
article_set
.
all
(),
[
'<Article: NASA uses Python>'
]
)
def
test_selects
(
self
):
def
test_selects
(
self
):
# We can perform kwarg queries across m2m relationships
# We can perform kwarg queries across m2m relationships
...
@@ -144,19 +156,22 @@ class ManyToManyTests(TestCase):
...
@@ -144,19 +156,22 @@ class ManyToManyTests(TestCase):
[
[
'<Article: Django lets you build Web apps easily>'
,
'<Article: Django lets you build Web apps easily>'
,
'<Article: NASA uses Python>'
,
'<Article: NASA uses Python>'
,
])
]
)
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
publications
=
self
.
p1
.
id
),
Article
.
objects
.
filter
(
publications
=
self
.
p1
.
id
),
[
[
'<Article: Django lets you build Web apps easily>'
,
'<Article: Django lets you build Web apps easily>'
,
'<Article: NASA uses Python>'
,
'<Article: NASA uses Python>'
,
])
]
)
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
publications
=
self
.
p1
),
Article
.
objects
.
filter
(
publications
=
self
.
p1
),
[
[
'<Article: Django lets you build Web apps easily>'
,
'<Article: Django lets you build Web apps easily>'
,
'<Article: NASA uses Python>'
,
'<Article: NASA uses Python>'
,
])
]
)
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
publications__title__startswith
=
"Science"
),
Article
.
objects
.
filter
(
publications__title__startswith
=
"Science"
),
[
[
...
@@ -164,14 +179,16 @@ class ManyToManyTests(TestCase):
...
@@ -164,14 +179,16 @@ class ManyToManyTests(TestCase):
'<Article: NASA uses Python>'
,
'<Article: NASA uses Python>'
,
'<Article: NASA uses Python>'
,
'<Article: NASA uses Python>'
,
'<Article: Oxygen-free diet works wonders>'
,
'<Article: Oxygen-free diet works wonders>'
,
])
]
)
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
publications__title__startswith
=
"Science"
)
.
distinct
(),
Article
.
objects
.
filter
(
publications__title__startswith
=
"Science"
)
.
distinct
(),
[
[
'<Article: NASA finds intelligent life on Earth>'
,
'<Article: NASA finds intelligent life on Earth>'
,
'<Article: NASA uses Python>'
,
'<Article: NASA uses Python>'
,
'<Article: Oxygen-free diet works wonders>'
,
'<Article: Oxygen-free diet works wonders>'
,
])
]
)
# The count() function respects distinct() as well.
# The count() function respects distinct() as well.
self
.
assertEqual
(
Article
.
objects
.
filter
(
publications__title__startswith
=
"Science"
)
.
count
(),
4
)
self
.
assertEqual
(
Article
.
objects
.
filter
(
publications__title__startswith
=
"Science"
)
.
count
(),
4
)
...
@@ -191,7 +208,8 @@ class ManyToManyTests(TestCase):
...
@@ -191,7 +208,8 @@ class ManyToManyTests(TestCase):
'<Article: NASA finds intelligent life on Earth>'
,
'<Article: NASA finds intelligent life on Earth>'
,
'<Article: NASA uses Python>'
,
'<Article: NASA uses Python>'
,
'<Article: Oxygen-free diet works wonders>'
,
'<Article: Oxygen-free diet works wonders>'
,
])
]
)
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
publications__in
=
[
self
.
p1
,
self
.
p2
])
.
distinct
(),
Article
.
objects
.
filter
(
publications__in
=
[
self
.
p1
,
self
.
p2
])
.
distinct
(),
[
[
...
@@ -199,20 +217,22 @@ class ManyToManyTests(TestCase):
...
@@ -199,20 +217,22 @@ class ManyToManyTests(TestCase):
'<Article: NASA finds intelligent life on Earth>'
,
'<Article: NASA finds intelligent life on Earth>'
,
'<Article: NASA uses Python>'
,
'<Article: NASA uses Python>'
,
'<Article: Oxygen-free diet works wonders>'
,
'<Article: Oxygen-free diet works wonders>'
,
])
]
)
# Excluding a related item works as you would expect, too (although the SQL
# Excluding a related item works as you would expect, too (although the SQL
# involved is a little complex).
# involved is a little complex).
self
.
assertQuerysetEqual
(
Article
.
objects
.
exclude
(
publications
=
self
.
p2
),
self
.
assertQuerysetEqual
(
[
'<Article: Django lets you build Web apps easily>'
])
Article
.
objects
.
exclude
(
publications
=
self
.
p2
),
[
'<Article: Django lets you build Web apps easily>'
]
)
def
test_reverse_selects
(
self
):
def
test_reverse_selects
(
self
):
# Reverse m2m queries are supported (i.e., starting at the table that
# Reverse m2m queries are supported (i.e., starting at the table that
# doesn't have a ManyToManyField).
# doesn't have a ManyToManyField).
self
.
assertQuerysetEqual
(
Publication
.
objects
.
filter
(
id__exact
=
self
.
p1
.
id
),
python_journal
=
[
'<Publication: The Python Journal>'
]
[
'<Publication: The Python Journal>'
])
self
.
assertQuerysetEqual
(
Publication
.
objects
.
filter
(
id__exact
=
self
.
p1
.
id
),
python_journal
)
self
.
assertQuerysetEqual
(
Publication
.
objects
.
filter
(
pk
=
self
.
p1
.
id
),
self
.
assertQuerysetEqual
(
Publication
.
objects
.
filter
(
pk
=
self
.
p1
.
id
),
python_journal
)
[
'<Publication: The Python Journal>'
])
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
Publication
.
objects
.
filter
(
article__headline__startswith
=
"NASA"
),
Publication
.
objects
.
filter
(
article__headline__startswith
=
"NASA"
),
[
[
...
@@ -222,14 +242,11 @@ class ManyToManyTests(TestCase):
...
@@ -222,14 +242,11 @@ class ManyToManyTests(TestCase):
'<Publication: Science Weekly>'
,
'<Publication: Science Weekly>'
,
'<Publication: The Python Journal>'
,
'<Publication: The Python Journal>'
,
])
])
self
.
assertQuerysetEqual
(
Publication
.
objects
.
filter
(
article__id__exact
=
self
.
a1
.
id
),
[
'<Publication: The Python Journal>'
])
self
.
assertQuerysetEqual
(
Publication
.
objects
.
filter
(
article__id__exact
=
self
.
a1
.
id
),
python_journal
)
self
.
assertQuerysetEqual
(
Publication
.
objects
.
filter
(
article__pk
=
self
.
a1
.
id
),
self
.
assertQuerysetEqual
(
Publication
.
objects
.
filter
(
article__pk
=
self
.
a1
.
id
),
python_journal
)
[
'<Publication: The Python Journal>'
])
self
.
assertQuerysetEqual
(
Publication
.
objects
.
filter
(
article
=
self
.
a1
.
id
),
python_journal
)
self
.
assertQuerysetEqual
(
Publication
.
objects
.
filter
(
article
=
self
.
a1
.
id
),
self
.
assertQuerysetEqual
(
Publication
.
objects
.
filter
(
article
=
self
.
a1
),
python_journal
)
[
'<Publication: The Python Journal>'
])
self
.
assertQuerysetEqual
(
Publication
.
objects
.
filter
(
article
=
self
.
a1
),
[
'<Publication: The Python Journal>'
])
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
Publication
.
objects
.
filter
(
article__in
=
[
self
.
a1
.
id
,
self
.
a2
.
id
])
.
distinct
(),
Publication
.
objects
.
filter
(
article__in
=
[
self
.
a1
.
id
,
self
.
a2
.
id
])
.
distinct
(),
...
@@ -259,47 +276,59 @@ class ManyToManyTests(TestCase):
...
@@ -259,47 +276,59 @@ class ManyToManyTests(TestCase):
def
test_delete
(
self
):
def
test_delete
(
self
):
# If we delete a Publication, its Articles won't be able to access it.
# If we delete a Publication, its Articles won't be able to access it.
self
.
p1
.
delete
()
self
.
p1
.
delete
()
self
.
assertQuerysetEqual
(
Publication
.
objects
.
all
(),
self
.
assertQuerysetEqual
(
Publication
.
objects
.
all
(),
[
[
'<Publication: Highlights for Children>'
,
'<Publication: Highlights for Children>'
,
'<Publication: Science News>'
,
'<Publication: Science News>'
,
'<Publication: Science Weekly>'
,
'<Publication: Science Weekly>'
,
])
]
)
self
.
assertQuerysetEqual
(
self
.
a1
.
publications
.
all
(),
[])
self
.
assertQuerysetEqual
(
self
.
a1
.
publications
.
all
(),
[])
# If we delete an Article, its Publications won't be able to access it.
# If we delete an Article, its Publications won't be able to access it.
self
.
a2
.
delete
()
self
.
a2
.
delete
()
self
.
assertQuerysetEqual
(
Article
.
objects
.
all
(),
self
.
assertQuerysetEqual
(
Article
.
objects
.
all
(),
[
[
'<Article: Django lets you build Web apps easily>'
,
'<Article: Django lets you build Web apps easily>'
,
'<Article: NASA finds intelligent life on Earth>'
,
'<Article: NASA finds intelligent life on Earth>'
,
'<Article: Oxygen-free diet works wonders>'
,
'<Article: Oxygen-free diet works wonders>'
,
])
]
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
)
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
[
[
'<Article: NASA finds intelligent life on Earth>'
,
'<Article: NASA finds intelligent life on Earth>'
,
'<Article: Oxygen-free diet works wonders>'
,
'<Article: Oxygen-free diet works wonders>'
,
])
]
)
def
test_bulk_delete
(
self
):
def
test_bulk_delete
(
self
):
# Bulk delete some Publications - references to deleted publications should go
# Bulk delete some Publications - references to deleted publications should go
Publication
.
objects
.
filter
(
title__startswith
=
'Science'
)
.
delete
()
Publication
.
objects
.
filter
(
title__startswith
=
'Science'
)
.
delete
()
self
.
assertQuerysetEqual
(
Publication
.
objects
.
all
(),
self
.
assertQuerysetEqual
(
Publication
.
objects
.
all
(),
[
[
'<Publication: Highlights for Children>'
,
'<Publication: Highlights for Children>'
,
'<Publication: The Python Journal>'
,
'<Publication: The Python Journal>'
,
])
]
self
.
assertQuerysetEqual
(
Article
.
objects
.
all
(),
)
self
.
assertQuerysetEqual
(
Article
.
objects
.
all
(),
[
[
'<Article: Django lets you build Web apps easily>'
,
'<Article: Django lets you build Web apps easily>'
,
'<Article: NASA finds intelligent life on Earth>'
,
'<Article: NASA finds intelligent life on Earth>'
,
'<Article: NASA uses Python>'
,
'<Article: NASA uses Python>'
,
'<Article: Oxygen-free diet works wonders>'
,
'<Article: Oxygen-free diet works wonders>'
,
])
]
self
.
assertQuerysetEqual
(
self
.
a2
.
publications
.
all
(),
)
self
.
assertQuerysetEqual
(
self
.
a2
.
publications
.
all
(),
[
[
'<Publication: Highlights for Children>'
,
'<Publication: Highlights for Children>'
,
'<Publication: The Python Journal>'
,
'<Publication: The Python Journal>'
,
])
]
)
# Bulk delete some articles - references to deleted objects should go
# Bulk delete some articles - references to deleted objects should go
q
=
Article
.
objects
.
filter
(
headline__startswith
=
'Django'
)
q
=
Article
.
objects
.
filter
(
headline__startswith
=
'Django'
)
...
@@ -308,46 +337,45 @@ class ManyToManyTests(TestCase):
...
@@ -308,46 +337,45 @@ class ManyToManyTests(TestCase):
# After the delete, the QuerySet cache needs to be cleared,
# After the delete, the QuerySet cache needs to be cleared,
# and the referenced objects should be gone
# and the referenced objects should be gone
self
.
assertQuerysetEqual
(
q
,
[])
self
.
assertQuerysetEqual
(
q
,
[])
self
.
assertQuerysetEqual
(
self
.
p1
.
article_set
.
all
(),
self
.
assertQuerysetEqual
(
self
.
p1
.
article_set
.
all
(),
[
'<Article: NASA uses Python>'
])
[
'<Article: NASA uses Python>'
])
def
test_remove
(
self
):
def
test_remove
(
self
):
# Removing publication from an article:
# Removing publication from an article:
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
[
[
'<Article: NASA finds intelligent life on Earth>'
,
'<Article: NASA finds intelligent life on Earth>'
,
'<Article: NASA uses Python>'
,
'<Article: NASA uses Python>'
,
'<Article: Oxygen-free diet works wonders>'
,
'<Article: Oxygen-free diet works wonders>'
,
])
]
)
self
.
a4
.
publications
.
remove
(
self
.
p2
)
self
.
a4
.
publications
.
remove
(
self
.
p2
)
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
[
[
'<Article: NASA finds intelligent life on Earth>'
,
'<Article: NASA finds intelligent life on Earth>'
,
'<Article: NASA uses Python>'
,
'<Article: NASA uses Python>'
,
])
]
)
self
.
assertQuerysetEqual
(
self
.
a4
.
publications
.
all
(),
[])
self
.
assertQuerysetEqual
(
self
.
a4
.
publications
.
all
(),
[])
# And from the other end
# And from the other end
self
.
p2
.
article_set
.
remove
(
self
.
a3
)
self
.
p2
.
article_set
.
remove
(
self
.
a3
)
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
[
'<Article: NASA uses Python>'
])
[
'<Article: NASA uses Python>'
,
])
self
.
assertQuerysetEqual
(
self
.
a3
.
publications
.
all
(),
[])
self
.
assertQuerysetEqual
(
self
.
a3
.
publications
.
all
(),
[])
def
test_set
(
self
):
def
test_set
(
self
):
self
.
p2
.
article_set
.
set
([
self
.
a4
,
self
.
a3
])
self
.
p2
.
article_set
.
set
([
self
.
a4
,
self
.
a3
])
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
[
[
'<Article: NASA finds intelligent life on Earth>'
,
'<Article: NASA finds intelligent life on Earth>'
,
'<Article: Oxygen-free diet works wonders>'
,
'<Article: Oxygen-free diet works wonders>'
,
]
)
]
self
.
assertQuerysetEqual
(
self
.
a4
.
publications
.
all
(),
)
[
'<Publication: Science News>'
])
self
.
assertQuerysetEqual
(
self
.
a4
.
publications
.
all
(),
[
'<Publication: Science News>'
])
self
.
a4
.
publications
.
set
([
self
.
p3
.
id
])
self
.
a4
.
publications
.
set
([
self
.
p3
.
id
])
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
[
'<Article: NASA finds intelligent life on Earth>'
])
[
'<Article: NASA finds intelligent life on Earth>'
])
self
.
assertQuerysetEqual
(
self
.
a4
.
publications
.
all
(),
[
'<Publication: Science Weekly>'
])
self
.
assertQuerysetEqual
(
self
.
a4
.
publications
.
all
(),
[
'<Publication: Science Weekly>'
])
self
.
p2
.
article_set
.
set
([])
self
.
p2
.
article_set
.
set
([])
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
[])
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
[])
...
@@ -355,18 +383,17 @@ class ManyToManyTests(TestCase):
...
@@ -355,18 +383,17 @@ class ManyToManyTests(TestCase):
self
.
assertQuerysetEqual
(
self
.
a4
.
publications
.
all
(),
[])
self
.
assertQuerysetEqual
(
self
.
a4
.
publications
.
all
(),
[])
self
.
p2
.
article_set
.
set
([
self
.
a4
,
self
.
a3
],
clear
=
True
)
self
.
p2
.
article_set
.
set
([
self
.
a4
,
self
.
a3
],
clear
=
True
)
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
[
[
'<Article: NASA finds intelligent life on Earth>'
,
'<Article: NASA finds intelligent life on Earth>'
,
'<Article: Oxygen-free diet works wonders>'
,
'<Article: Oxygen-free diet works wonders>'
,
]
)
]
self
.
assertQuerysetEqual
(
self
.
a4
.
publications
.
all
(),
)
[
'<Publication: Science News>'
])
self
.
assertQuerysetEqual
(
self
.
a4
.
publications
.
all
(),
[
'<Publication: Science News>'
])
self
.
a4
.
publications
.
set
([
self
.
p3
.
id
],
clear
=
True
)
self
.
a4
.
publications
.
set
([
self
.
p3
.
id
],
clear
=
True
)
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
[
'<Article: NASA finds intelligent life on Earth>'
])
[
'<Article: NASA finds intelligent life on Earth>'
])
self
.
assertQuerysetEqual
(
self
.
a4
.
publications
.
all
(),
[
'<Publication: Science Weekly>'
])
self
.
assertQuerysetEqual
(
self
.
a4
.
publications
.
all
(),
[
'<Publication: Science Weekly>'
])
self
.
p2
.
article_set
.
set
([],
clear
=
True
)
self
.
p2
.
article_set
.
set
([],
clear
=
True
)
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
[])
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
[])
...
@@ -385,18 +412,17 @@ class ManyToManyTests(TestCase):
...
@@ -385,18 +412,17 @@ class ManyToManyTests(TestCase):
@ignore_warnings
(
category
=
RemovedInDjango20Warning
)
@ignore_warnings
(
category
=
RemovedInDjango20Warning
)
def
test_assign_deprecated
(
self
):
def
test_assign_deprecated
(
self
):
self
.
p2
.
article_set
=
[
self
.
a4
,
self
.
a3
]
self
.
p2
.
article_set
=
[
self
.
a4
,
self
.
a3
]
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
[
[
'<Article: NASA finds intelligent life on Earth>'
,
'<Article: NASA finds intelligent life on Earth>'
,
'<Article: Oxygen-free diet works wonders>'
,
'<Article: Oxygen-free diet works wonders>'
,
]
)
]
self
.
assertQuerysetEqual
(
self
.
a4
.
publications
.
all
(),
)
[
'<Publication: Science News>'
])
self
.
assertQuerysetEqual
(
self
.
a4
.
publications
.
all
(),
[
'<Publication: Science News>'
])
self
.
a4
.
publications
=
[
self
.
p3
.
id
]
self
.
a4
.
publications
=
[
self
.
p3
.
id
]
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
[
'<Article: NASA finds intelligent life on Earth>'
])
[
'<Article: NASA finds intelligent life on Earth>'
])
self
.
assertQuerysetEqual
(
self
.
a4
.
publications
.
all
(),
[
'<Publication: Science Weekly>'
])
self
.
assertQuerysetEqual
(
self
.
a4
.
publications
.
all
(),
[
'<Publication: Science Weekly>'
])
# An alternate to calling clear() is to assign the empty set
# An alternate to calling clear() is to assign the empty set
self
.
p2
.
article_set
=
[]
self
.
p2
.
article_set
=
[]
...
@@ -427,18 +453,17 @@ class ManyToManyTests(TestCase):
...
@@ -427,18 +453,17 @@ class ManyToManyTests(TestCase):
def
test_assign_ids
(
self
):
def
test_assign_ids
(
self
):
# Relation sets can also be set using primary key values
# Relation sets can also be set using primary key values
self
.
p2
.
article_set
.
set
([
self
.
a4
.
id
,
self
.
a3
.
id
])
self
.
p2
.
article_set
.
set
([
self
.
a4
.
id
,
self
.
a3
.
id
])
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
[
[
'<Article: NASA finds intelligent life on Earth>'
,
'<Article: NASA finds intelligent life on Earth>'
,
'<Article: Oxygen-free diet works wonders>'
,
'<Article: Oxygen-free diet works wonders>'
,
]
)
]
self
.
assertQuerysetEqual
(
self
.
a4
.
publications
.
all
(),
)
[
'<Publication: Science News>'
])
self
.
assertQuerysetEqual
(
self
.
a4
.
publications
.
all
(),
[
'<Publication: Science News>'
])
self
.
a4
.
publications
.
set
([
self
.
p3
.
id
])
self
.
a4
.
publications
.
set
([
self
.
p3
.
id
])
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
[
'<Article: NASA finds intelligent life on Earth>'
])
[
'<Article: NASA finds intelligent life on Earth>'
])
self
.
assertQuerysetEqual
(
self
.
a4
.
publications
.
all
(),
[
'<Publication: Science Weekly>'
])
self
.
assertQuerysetEqual
(
self
.
a4
.
publications
.
all
(),
[
'<Publication: Science Weekly>'
])
def
test_forward_assign_with_queryset
(
self
):
def
test_forward_assign_with_queryset
(
self
):
# Ensure that querysets used in m2m assignments are pre-evaluated
# Ensure that querysets used in m2m assignments are pre-evaluated
...
@@ -472,19 +497,17 @@ class ManyToManyTests(TestCase):
...
@@ -472,19 +497,17 @@ class ManyToManyTests(TestCase):
# And you can clear from the other end
# And you can clear from the other end
self
.
p2
.
article_set
.
add
(
self
.
a3
,
self
.
a4
)
self
.
p2
.
article_set
.
add
(
self
.
a3
,
self
.
a4
)
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
[
[
'<Article: NASA finds intelligent life on Earth>'
,
'<Article: NASA finds intelligent life on Earth>'
,
'<Article: Oxygen-free diet works wonders>'
,
'<Article: Oxygen-free diet works wonders>'
,
])
]
self
.
assertQuerysetEqual
(
self
.
a4
.
publications
.
all
(),
)
[
self
.
assertQuerysetEqual
(
self
.
a4
.
publications
.
all
(),
[
'<Publication: Science News>'
])
'<Publication: Science News>'
,
])
self
.
a4
.
publications
.
clear
()
self
.
a4
.
publications
.
clear
()
self
.
assertQuerysetEqual
(
self
.
a4
.
publications
.
all
(),
[])
self
.
assertQuerysetEqual
(
self
.
a4
.
publications
.
all
(),
[])
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
self
.
assertQuerysetEqual
(
self
.
p2
.
article_set
.
all
(),
[
'<Article: NASA finds intelligent life on Earth>'
])
[
'<Article: NASA finds intelligent life on Earth>'
])
def
test_inherited_models_selects
(
self
):
def
test_inherited_models_selects
(
self
):
"""
"""
...
@@ -494,19 +517,19 @@ class ManyToManyTests(TestCase):
...
@@ -494,19 +517,19 @@ class ManyToManyTests(TestCase):
a
=
InheritedArticleA
.
objects
.
create
()
a
=
InheritedArticleA
.
objects
.
create
()
b
=
InheritedArticleB
.
objects
.
create
()
b
=
InheritedArticleB
.
objects
.
create
()
a
.
publications
.
add
(
self
.
p1
,
self
.
p2
)
a
.
publications
.
add
(
self
.
p1
,
self
.
p2
)
self
.
assertQuerysetEqual
(
a
.
publications
.
all
(),
self
.
assertQuerysetEqual
(
a
.
publications
.
all
(),
[
[
'<Publication: Science News>'
,
'<Publication: Science News>'
,
'<Publication: The Python Journal>'
,
'<Publication: The Python Journal>'
,
])
])
self
.
assertQuerysetEqual
(
b
.
publications
.
all
(),
[])
self
.
assertQuerysetEqual
(
b
.
publications
.
all
(),
[])
b
.
publications
.
add
(
self
.
p3
)
b
.
publications
.
add
(
self
.
p3
)
self
.
assertQuerysetEqual
(
a
.
publications
.
all
(),
self
.
assertQuerysetEqual
(
a
.
publications
.
all
(),
[
[
'<Publication: Science News>'
,
'<Publication: Science News>'
,
'<Publication: The Python Journal>'
,
'<Publication: The Python Journal>'
,
])
]
self
.
assertQuerysetEqual
(
b
.
publications
.
all
(),
)
[
self
.
assertQuerysetEqual
(
b
.
publications
.
all
(),
[
'<Publication: Science Weekly>'
])
'<Publication: Science Weekly>'
,
])
tests/many_to_one/tests.py
Dosyayı görüntüle @
406675b1
...
@@ -22,8 +22,7 @@ class ManyToOneTests(TestCase):
...
@@ -22,8 +22,7 @@ class ManyToOneTests(TestCase):
self
.
r2
=
Reporter
(
first_name
=
'Paul'
,
last_name
=
'Jones'
,
email
=
'paul@example.com'
)
self
.
r2
=
Reporter
(
first_name
=
'Paul'
,
last_name
=
'Jones'
,
email
=
'paul@example.com'
)
self
.
r2
.
save
()
self
.
r2
.
save
()
# Create an Article.
# Create an Article.
self
.
a
=
Article
(
id
=
None
,
headline
=
"This is a test"
,
self
.
a
=
Article
(
headline
=
"This is a test"
,
pub_date
=
datetime
.
date
(
2005
,
7
,
27
),
reporter
=
self
.
r
)
pub_date
=
datetime
.
date
(
2005
,
7
,
27
),
reporter
=
self
.
r
)
self
.
a
.
save
()
self
.
a
.
save
()
def
test_get
(
self
):
def
test_get
(
self
):
...
@@ -38,21 +37,18 @@ class ManyToOneTests(TestCase):
...
@@ -38,21 +37,18 @@ class ManyToOneTests(TestCase):
def
test_create
(
self
):
def
test_create
(
self
):
# You can also instantiate an Article by passing the Reporter's ID
# You can also instantiate an Article by passing the Reporter's ID
# instead of a Reporter object.
# instead of a Reporter object.
a3
=
Article
(
id
=
None
,
headline
=
"Third article"
,
a3
=
Article
(
headline
=
"Third article"
,
pub_date
=
datetime
.
date
(
2005
,
7
,
27
),
reporter_id
=
self
.
r
.
id
)
pub_date
=
datetime
.
date
(
2005
,
7
,
27
),
reporter_id
=
self
.
r
.
id
)
a3
.
save
()
a3
.
save
()
self
.
assertEqual
(
a3
.
reporter
.
id
,
self
.
r
.
id
)
self
.
assertEqual
(
a3
.
reporter
.
id
,
self
.
r
.
id
)
# Similarly, the reporter ID can be a string.
# Similarly, the reporter ID can be a string.
a4
=
Article
(
id
=
None
,
headline
=
"Fourth article"
,
a4
=
Article
(
headline
=
"Fourth article"
,
pub_date
=
datetime
.
date
(
2005
,
7
,
27
),
reporter_id
=
str
(
self
.
r
.
id
))
pub_date
=
datetime
.
date
(
2005
,
7
,
27
),
reporter_id
=
str
(
self
.
r
.
id
))
a4
.
save
()
a4
.
save
()
self
.
assertEqual
(
repr
(
a4
.
reporter
),
"<Reporter: John Smith>"
)
self
.
assertEqual
(
repr
(
a4
.
reporter
),
"<Reporter: John Smith>"
)
def
test_add
(
self
):
def
test_add
(
self
):
# Create an Article via the Reporter object.
# Create an Article via the Reporter object.
new_article
=
self
.
r
.
article_set
.
create
(
headline
=
"John's second story"
,
new_article
=
self
.
r
.
article_set
.
create
(
headline
=
"John's second story"
,
pub_date
=
datetime
.
date
(
2005
,
7
,
29
))
pub_date
=
datetime
.
date
(
2005
,
7
,
29
))
self
.
assertEqual
(
repr
(
new_article
),
"<Article: John's second story>"
)
self
.
assertEqual
(
repr
(
new_article
),
"<Article: John's second story>"
)
self
.
assertEqual
(
new_article
.
reporter
.
id
,
self
.
r
.
id
)
self
.
assertEqual
(
new_article
.
reporter
.
id
,
self
.
r
.
id
)
...
@@ -64,12 +60,10 @@ class ManyToOneTests(TestCase):
...
@@ -64,12 +60,10 @@ class ManyToOneTests(TestCase):
self
.
r
.
article_set
.
add
(
new_article2
,
bulk
=
False
)
self
.
r
.
article_set
.
add
(
new_article2
,
bulk
=
False
)
self
.
assertEqual
(
new_article2
.
reporter
.
id
,
self
.
r
.
id
)
self
.
assertEqual
(
new_article2
.
reporter
.
id
,
self
.
r
.
id
)
self
.
assertQuerysetEqual
(
self
.
r
.
article_set
.
all
(),
self
.
assertQuerysetEqual
(
[
self
.
r
.
article_set
.
all
(),
"<Article: John's second story>"
,
[
"<Article: John's second story>"
,
"<Article: Paul's story>"
,
"<Article: This is a test>"
]
"<Article: Paul's story>"
,
)
"<Article: This is a test>"
,
])
# Add the same article to a different article set - check that it moves.
# Add the same article to a different article set - check that it moves.
self
.
r2
.
article_set
.
add
(
new_article2
)
self
.
r2
.
article_set
.
add
(
new_article2
)
...
@@ -81,17 +75,14 @@ class ManyToOneTests(TestCase):
...
@@ -81,17 +75,14 @@ class ManyToOneTests(TestCase):
with
six
.
assertRaisesRegex
(
self
,
TypeError
,
with
six
.
assertRaisesRegex
(
self
,
TypeError
,
"'Article' instance expected, got <Reporter.*"
):
"'Article' instance expected, got <Reporter.*"
):
self
.
r
.
article_set
.
add
(
self
.
r2
)
self
.
r
.
article_set
.
add
(
self
.
r2
)
self
.
assertQuerysetEqual
(
self
.
r
.
article_set
.
all
(),
self
.
assertQuerysetEqual
(
[
self
.
r
.
article_set
.
all
(),
"<Article: John's second story>"
,
[
"<Article: John's second story>"
,
"<Article: This is a test>"
]
"<Article: This is a test>"
,
)
])
def
test_set
(
self
):
def
test_set
(
self
):
new_article
=
self
.
r
.
article_set
.
create
(
headline
=
"John's second story"
,
new_article
=
self
.
r
.
article_set
.
create
(
headline
=
"John's second story"
,
pub_date
=
datetime
.
date
(
2005
,
7
,
29
))
pub_date
=
datetime
.
date
(
2005
,
7
,
29
))
new_article2
=
self
.
r2
.
article_set
.
create
(
headline
=
"Paul's story"
,
pub_date
=
datetime
.
date
(
2006
,
1
,
17
))
new_article2
=
self
.
r2
.
article_set
.
create
(
headline
=
"Paul's story"
,
pub_date
=
datetime
.
date
(
2006
,
1
,
17
))
# Assign the article to the reporter.
# Assign the article to the reporter.
new_article2
.
reporter
=
self
.
r
new_article2
.
reporter
=
self
.
r
...
@@ -108,20 +99,18 @@ class ManyToOneTests(TestCase):
...
@@ -108,20 +99,18 @@ class ManyToOneTests(TestCase):
# Set the article back again.
# Set the article back again.
self
.
r2
.
article_set
.
set
([
new_article
,
new_article2
])
self
.
r2
.
article_set
.
set
([
new_article
,
new_article2
])
self
.
assertQuerysetEqual
(
self
.
r
.
article_set
.
all
(),
[
"<Article: This is a test>"
])
self
.
assertQuerysetEqual
(
self
.
r
.
article_set
.
all
(),
[
"<Article: This is a test>"
])
self
.
assertQuerysetEqual
(
self
.
r2
.
article_set
.
all
(),
self
.
assertQuerysetEqual
(
[
self
.
r2
.
article_set
.
all
(),
"<Article: John's second story>"
,
[
"<Article: John's second story>"
,
"<Article: Paul's story>"
]
"<Article: Paul's story>"
,
)
])
# Funny case - because the ForeignKey cannot be null,
# Funny case - because the ForeignKey cannot be null,
# existing members of the set must remain.
# existing members of the set must remain.
self
.
r
.
article_set
.
set
([
new_article
])
self
.
r
.
article_set
.
set
([
new_article
])
self
.
assertQuerysetEqual
(
self
.
r
.
article_set
.
all
(),
self
.
assertQuerysetEqual
(
[
self
.
r
.
article_set
.
all
(),
"<Article: John's second story>"
,
[
"<Article: John's second story>"
,
"<Article: This is a test>"
]
"<Article: This is a test>"
,
)
])
self
.
assertQuerysetEqual
(
self
.
r2
.
article_set
.
all
(),
[
"<Article: Paul's story>"
])
self
.
assertQuerysetEqual
(
self
.
r2
.
article_set
.
all
(),
[
"<Article: Paul's story>"
])
def
test_reverse_assignment_deprecation
(
self
):
def
test_reverse_assignment_deprecation
(
self
):
...
@@ -134,10 +123,8 @@ class ManyToOneTests(TestCase):
...
@@ -134,10 +123,8 @@ class ManyToOneTests(TestCase):
self
.
r2
.
article_set
=
[]
self
.
r2
.
article_set
=
[]
def
test_assign
(
self
):
def
test_assign
(
self
):
new_article
=
self
.
r
.
article_set
.
create
(
headline
=
"John's second story"
,
new_article
=
self
.
r
.
article_set
.
create
(
headline
=
"John's second story"
,
pub_date
=
datetime
.
date
(
2005
,
7
,
29
))
pub_date
=
datetime
.
date
(
2005
,
7
,
29
))
new_article2
=
self
.
r2
.
article_set
.
create
(
headline
=
"Paul's story"
,
pub_date
=
datetime
.
date
(
2006
,
1
,
17
))
new_article2
=
self
.
r2
.
article_set
.
create
(
headline
=
"Paul's story"
,
pub_date
=
datetime
.
date
(
2006
,
1
,
17
))
# Assign the article to the reporter directly using the descriptor.
# Assign the article to the reporter directly using the descriptor.
new_article2
.
reporter
=
self
.
r
new_article2
.
reporter
=
self
.
r
...
@@ -154,73 +141,59 @@ class ManyToOneTests(TestCase):
...
@@ -154,73 +141,59 @@ class ManyToOneTests(TestCase):
# Set the article back again using set() method.
# Set the article back again using set() method.
self
.
r2
.
article_set
.
set
([
new_article
,
new_article2
])
self
.
r2
.
article_set
.
set
([
new_article
,
new_article2
])
self
.
assertQuerysetEqual
(
self
.
r
.
article_set
.
all
(),
[
"<Article: This is a test>"
])
self
.
assertQuerysetEqual
(
self
.
r
.
article_set
.
all
(),
[
"<Article: This is a test>"
])
self
.
assertQuerysetEqual
(
self
.
r2
.
article_set
.
all
(),
self
.
assertQuerysetEqual
(
[
self
.
r2
.
article_set
.
all
(),
"<Article: John's second story>"
,
[
"<Article: John's second story>"
,
"<Article: Paul's story>"
]
"<Article: Paul's story>"
,
)
])
# Because the ForeignKey cannot be null, existing members of the set
# Because the ForeignKey cannot be null, existing members of the set
# must remain.
# must remain.
self
.
r
.
article_set
.
set
([
new_article
])
self
.
r
.
article_set
.
set
([
new_article
])
self
.
assertQuerysetEqual
(
self
.
r
.
article_set
.
all
(),
self
.
assertQuerysetEqual
(
[
self
.
r
.
article_set
.
all
(),
"<Article: John's second story>"
,
[
"<Article: John's second story>"
,
"<Article: This is a test>"
]
"<Article: This is a test>"
,
)
])
self
.
assertQuerysetEqual
(
self
.
r2
.
article_set
.
all
(),
[
"<Article: Paul's story>"
])
self
.
assertQuerysetEqual
(
self
.
r2
.
article_set
.
all
(),
[
"<Article: Paul's story>"
])
# Reporter cannot be null - there should not be a clear or remove method
# Reporter cannot be null - there should not be a clear or remove method
self
.
assertFalse
(
hasattr
(
self
.
r2
.
article_set
,
'remove'
))
self
.
assertFalse
(
hasattr
(
self
.
r2
.
article_set
,
'remove'
))
self
.
assertFalse
(
hasattr
(
self
.
r2
.
article_set
,
'clear'
))
self
.
assertFalse
(
hasattr
(
self
.
r2
.
article_set
,
'clear'
))
def
test_selects
(
self
):
def
test_selects
(
self
):
self
.
r
.
article_set
.
create
(
headline
=
"John's second story"
,
self
.
r
.
article_set
.
create
(
headline
=
"John's second story"
,
pub_date
=
datetime
.
date
(
2005
,
7
,
29
))
pub_date
=
datetime
.
date
(
2005
,
7
,
29
))
self
.
r2
.
article_set
.
create
(
headline
=
"Paul's story"
,
pub_date
=
datetime
.
date
(
2006
,
1
,
17
))
self
.
r2
.
article_set
.
create
(
headline
=
"Paul's story"
,
pub_date
=
datetime
.
date
(
2006
,
1
,
17
))
# Reporter objects have access to their related Article objects.
# Reporter objects have access to their related Article objects.
self
.
assertQuerysetEqual
(
self
.
r
.
article_set
.
all
(),
[
self
.
assertQuerysetEqual
(
self
.
r
.
article_set
.
all
(),
[
"<Article: John's second story>"
,
"<Article: John's second story>"
,
"<Article: This is a test>"
,
"<Article: This is a test>"
,
])
])
self
.
assertQuerysetEqual
(
self
.
r
.
article_set
.
filter
(
headline__startswith
=
'This'
),
self
.
assertQuerysetEqual
(
self
.
r
.
article_set
.
filter
(
headline__startswith
=
'This'
),
[
"<Article: This is a test>"
])
[
"<Article: This is a test>"
])
self
.
assertEqual
(
self
.
r
.
article_set
.
count
(),
2
)
self
.
assertEqual
(
self
.
r
.
article_set
.
count
(),
2
)
self
.
assertEqual
(
self
.
r2
.
article_set
.
count
(),
1
)
self
.
assertEqual
(
self
.
r2
.
article_set
.
count
(),
1
)
# Get articles by id
# Get articles by id
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
id__exact
=
self
.
a
.
id
),
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
id__exact
=
self
.
a
.
id
),
[
"<Article: This is a test>"
])
[
"<Article: This is a test>"
])
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
pk
=
self
.
a
.
id
),
[
"<Article: This is a test>"
])
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
pk
=
self
.
a
.
id
),
[
"<Article: This is a test>"
])
# Query on an article property
# Query on an article property
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__startswith
=
'This'
),
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
headline__startswith
=
'This'
),
[
"<Article: This is a test>"
])
[
"<Article: This is a test>"
])
# The API automatically follows relationships as far as you need.
# The API automatically follows relationships as far as you need.
# Use double underscores to separate relationships.
# Use double underscores to separate relationships.
# This works as many levels deep as you want. There's no limit.
# This works as many levels deep as you want. There's no limit.
# Find all Articles for any Reporter whose first name is "John".
# Find all Articles for any Reporter whose first name is "John".
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
reporter__first_name__exact
=
'John'
),
self
.
assertQuerysetEqual
(
[
Article
.
objects
.
filter
(
reporter__first_name__exact
=
'John'
),
"<Article: John's second story>"
,
[
"<Article: John's second story>"
,
"<Article: This is a test>"
]
"<Article: This is a test>"
,
)
])
# Check that implied __exact also works
# Check that implied __exact also works
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
reporter__first_name
=
'John'
),
self
.
assertQuerysetEqual
(
[
Article
.
objects
.
filter
(
reporter__first_name
=
'John'
),
"<Article: John's second story>"
,
[
"<Article: John's second story>"
,
"<Article: This is a test>"
]
"<Article: This is a test>"
,
)
])
# Query twice over the related field.
# Query twice over the related field.
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
reporter__first_name__exact
=
'John'
,
Article
.
objects
.
filter
(
reporter__first_name__exact
=
'John'
,
reporter__last_name__exact
=
'Smith'
),
reporter__last_name__exact
=
'Smith'
),
[
"<Article: John's second story>"
,
"<Article: This is a test>"
]
[
)
"<Article: John's second story>"
,
"<Article: This is a test>"
,
])
# The underlying query only makes one join when a related table is referenced twice.
# The underlying query only makes one join when a related table is referenced twice.
queryset
=
Article
.
objects
.
filter
(
reporter__first_name__exact
=
'John'
,
queryset
=
Article
.
objects
.
filter
(
reporter__first_name__exact
=
'John'
,
reporter__last_name__exact
=
'Smith'
)
reporter__last_name__exact
=
'Smith'
)
self
.
assertNumQueries
(
1
,
list
,
queryset
)
self
.
assertNumQueries
(
1
,
list
,
queryset
)
self
.
assertEqual
(
queryset
.
query
.
get_compiler
(
queryset
.
db
)
.
as_sql
()[
0
]
.
count
(
'INNER JOIN'
),
1
)
self
.
assertEqual
(
queryset
.
query
.
get_compiler
(
queryset
.
db
)
.
as_sql
()[
0
]
.
count
(
'INNER JOIN'
),
1
)
...
@@ -228,19 +201,15 @@ class ManyToOneTests(TestCase):
...
@@ -228,19 +201,15 @@ class ManyToOneTests(TestCase):
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
reporter__first_name__exact
=
'John'
)
.
extra
(
Article
.
objects
.
filter
(
reporter__first_name__exact
=
'John'
)
.
extra
(
where
=
[
"many_to_one_reporter.last_name='Smith'"
]),
where
=
[
"many_to_one_reporter.last_name='Smith'"
]),
[
[
"<Article: John's second story>"
,
"<Article: This is a test>"
]
"<Article: John's second story>"
,
)
"<Article: This is a test>"
,
])
# ... and should work fine with the unicode that comes out of forms.Form.cleaned_data
# ... and should work fine with the unicode that comes out of forms.Form.cleaned_data
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
(
Article
.
objects
(
Article
.
objects
.
filter
(
reporter__first_name__exact
=
'John'
)
.
filter
(
reporter__first_name__exact
=
'John'
)
.
extra
(
where
=
[
"many_to_one_reporter.last_name='
%
s'"
%
'Smith'
])),
.
extra
(
where
=
[
"many_to_one_reporter.last_name='
%
s'"
%
'Smith'
])),
[
[
"<Article: John's second story>"
,
"<Article: This is a test>"
]
"<Article: John's second story>"
,
)
"<Article: This is a test>"
,
])
# Find all Articles for a Reporter.
# Find all Articles for a Reporter.
# Use direct ID check, pk check, and object comparison
# Use direct ID check, pk check, and object comparison
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
...
@@ -294,49 +263,39 @@ class ManyToOneTests(TestCase):
...
@@ -294,49 +263,39 @@ class ManyToOneTests(TestCase):
])
])
def
test_reverse_selects
(
self
):
def
test_reverse_selects
(
self
):
a3
=
Article
.
objects
.
create
(
id
=
None
,
headline
=
"Third article"
,
a3
=
Article
.
objects
.
create
(
pub_date
=
datetime
.
date
(
2005
,
7
,
27
),
reporter_id
=
self
.
r
.
id
)
headline
=
"Third article"
,
Article
.
objects
.
create
(
id
=
None
,
headline
=
"Fourth article"
,
pub_date
=
datetime
.
date
(
2005
,
7
,
27
),
pub_date
=
datetime
.
date
(
2005
,
7
,
27
),
reporter_id
=
str
(
self
.
r
.
id
))
reporter_id
=
self
.
r
.
id
,
)
Article
.
objects
.
create
(
headline
=
"Fourth article"
,
pub_date
=
datetime
.
date
(
2005
,
7
,
27
),
reporter_id
=
self
.
r
.
id
,
)
john_smith
=
[
"<Reporter: John Smith>"
]
# Reporters can be queried
# Reporters can be queried
self
.
assertQuerysetEqual
(
Reporter
.
objects
.
filter
(
id__exact
=
self
.
r
.
id
),
self
.
assertQuerysetEqual
(
Reporter
.
objects
.
filter
(
id__exact
=
self
.
r
.
id
),
john_smith
)
[
"<Reporter: John Smith>"
])
self
.
assertQuerysetEqual
(
Reporter
.
objects
.
filter
(
pk
=
self
.
r
.
id
),
john_smith
)
self
.
assertQuerysetEqual
(
Reporter
.
objects
.
filter
(
pk
=
self
.
r
.
id
),
self
.
assertQuerysetEqual
(
Reporter
.
objects
.
filter
(
first_name__startswith
=
'John'
),
john_smith
)
[
"<Reporter: John Smith>"
])
self
.
assertQuerysetEqual
(
Reporter
.
objects
.
filter
(
first_name__startswith
=
'John'
),
[
"<Reporter: John Smith>"
])
# Reporters can query in opposite direction of ForeignKey definition
# Reporters can query in opposite direction of ForeignKey definition
self
.
assertQuerysetEqual
(
Reporter
.
objects
.
filter
(
article__id__exact
=
self
.
a
.
id
),
self
.
assertQuerysetEqual
(
Reporter
.
objects
.
filter
(
article__id__exact
=
self
.
a
.
id
),
john_smith
)
[
"<Reporter: John Smith>"
])
self
.
assertQuerysetEqual
(
Reporter
.
objects
.
filter
(
article__pk
=
self
.
a
.
id
),
john_smith
)
self
.
assertQuerysetEqual
(
Reporter
.
objects
.
filter
(
article__pk
=
self
.
a
.
id
),
self
.
assertQuerysetEqual
(
Reporter
.
objects
.
filter
(
article
=
self
.
a
.
id
),
john_smith
)
[
"<Reporter: John Smith>"
])
self
.
assertQuerysetEqual
(
Reporter
.
objects
.
filter
(
article
=
self
.
a
),
john_smith
)
self
.
assertQuerysetEqual
(
Reporter
.
objects
.
filter
(
article
=
self
.
a
.
id
),
self
.
assertQuerysetEqual
(
Reporter
.
objects
.
filter
(
article__in
=
[
self
.
a
.
id
,
a3
.
id
])
.
distinct
(),
john_smith
)
[
"<Reporter: John Smith>"
])
self
.
assertQuerysetEqual
(
Reporter
.
objects
.
filter
(
article__in
=
[
self
.
a
.
id
,
a3
])
.
distinct
(),
john_smith
)
self
.
assertQuerysetEqual
(
Reporter
.
objects
.
filter
(
article
=
self
.
a
),
self
.
assertQuerysetEqual
(
Reporter
.
objects
.
filter
(
article__in
=
[
self
.
a
,
a3
])
.
distinct
(),
john_smith
)
[
"<Reporter: John Smith>"
])
self
.
assertQuerysetEqual
(
Reporter
.
objects
.
filter
(
article__in
=
[
self
.
a
.
id
,
a3
.
id
])
.
distinct
(),
[
"<Reporter: John Smith>"
])
self
.
assertQuerysetEqual
(
Reporter
.
objects
.
filter
(
article__in
=
[
self
.
a
.
id
,
a3
])
.
distinct
(),
[
"<Reporter: John Smith>"
])
self
.
assertQuerysetEqual
(
Reporter
.
objects
.
filter
(
article__in
=
[
self
.
a
,
a3
])
.
distinct
(),
[
"<Reporter: John Smith>"
])
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
Reporter
.
objects
.
filter
(
article__headline__startswith
=
'T'
),
Reporter
.
objects
.
filter
(
article__headline__startswith
=
'T'
),
[
"<Reporter: John Smith>"
,
"<Reporter: John Smith>"
],
[
"<Reporter: John Smith>"
,
"<Reporter: John Smith>"
],
ordered
=
False
ordered
=
False
)
)
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
Reporter
.
objects
.
filter
(
article__headline__startswith
=
'T'
)
.
distinct
(),
john_smith
)
Reporter
.
objects
.
filter
(
article__headline__startswith
=
'T'
)
.
distinct
(),
[
"<Reporter: John Smith>"
])
# Counting in the opposite direction works in conjunction with distinct()
# Counting in the opposite direction works in conjunction with distinct()
self
.
assertEqual
(
self
.
assertEqual
(
Reporter
.
objects
.
filter
(
article__headline__startswith
=
'T'
)
.
count
(),
2
)
Reporter
.
objects
.
filter
(
article__headline__startswith
=
'T'
)
.
count
(),
2
)
self
.
assertEqual
(
Reporter
.
objects
.
filter
(
article__headline__startswith
=
'T'
)
.
distinct
()
.
count
(),
1
)
self
.
assertEqual
(
Reporter
.
objects
.
filter
(
article__headline__startswith
=
'T'
)
.
distinct
()
.
count
(),
1
)
# Queries can go round in circles.
# Queries can go round in circles.
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
...
@@ -350,23 +309,21 @@ class ManyToOneTests(TestCase):
...
@@ -350,23 +309,21 @@ class ManyToOneTests(TestCase):
)
)
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
Reporter
.
objects
.
filter
(
article__reporter__first_name__startswith
=
'John'
)
.
distinct
(),
Reporter
.
objects
.
filter
(
article__reporter__first_name__startswith
=
'John'
)
.
distinct
(),
[
"<Reporter: John Smith>"
])
john_smith
self
.
assertQuerysetEqual
(
)
Reporter
.
objects
.
filter
(
article__reporter__exact
=
self
.
r
)
.
distinct
(),
self
.
assertQuerysetEqual
(
Reporter
.
objects
.
filter
(
article__reporter__exact
=
self
.
r
)
.
distinct
(),
john_smith
)
[
"<Reporter: John Smith>"
])
# Check that implied __exact also works.
# Check that implied __exact also works.
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
Reporter
.
objects
.
filter
(
article__reporter
=
self
.
r
)
.
distinct
(),
john_smith
)
Reporter
.
objects
.
filter
(
article__reporter
=
self
.
r
)
.
distinct
(),
[
"<Reporter: John Smith>"
])
# It's possible to use values() calls across many-to-one relations.
# It's possible to use values() calls across many-to-one relations.
# (Note, too, that we clear the ordering here so as not to drag the
# (Note, too, that we clear the ordering here so as not to drag the
# 'headline' field into the columns being used to determine uniqueness)
# 'headline' field into the columns being used to determine uniqueness)
d
=
{
'reporter__first_name'
:
'John'
,
'reporter__last_name'
:
'Smith'
}
d
=
{
'reporter__first_name'
:
'John'
,
'reporter__last_name'
:
'Smith'
}
self
.
assertEqual
([
d
],
qs
=
Article
.
objects
.
filter
(
list
(
Article
.
objects
.
filter
(
reporter
=
self
.
r
)
.
distinct
()
.
order_by
()
reporter
=
self
.
r
,
.
values
(
'reporter__first_name'
,
'reporter__last_name'
)))
)
.
distinct
()
.
order_by
()
.
values
(
'reporter__first_name'
,
'reporter__last_name'
)
self
.
assertEqual
([
d
],
list
(
qs
))
def
test_select_related
(
self
):
def
test_select_related
(
self
):
# Check that Article.objects.select_related().dates() works properly when
# Check that Article.objects.select_related().dates() works properly when
...
@@ -376,55 +333,54 @@ class ManyToOneTests(TestCase):
...
@@ -376,55 +333,54 @@ class ManyToOneTests(TestCase):
r2
=
Reporter
.
objects
.
create
(
first_name
=
'John'
,
last_name
=
'Kass'
,
email
=
'jkass@tribune.com'
)
r2
=
Reporter
.
objects
.
create
(
first_name
=
'John'
,
last_name
=
'Kass'
,
email
=
'jkass@tribune.com'
)
Article
.
objects
.
create
(
headline
=
'First'
,
pub_date
=
datetime
.
date
(
1980
,
4
,
23
),
reporter
=
r1
)
Article
.
objects
.
create
(
headline
=
'First'
,
pub_date
=
datetime
.
date
(
1980
,
4
,
23
),
reporter
=
r1
)
Article
.
objects
.
create
(
headline
=
'Second'
,
pub_date
=
datetime
.
date
(
1980
,
4
,
23
),
reporter
=
r2
)
Article
.
objects
.
create
(
headline
=
'Second'
,
pub_date
=
datetime
.
date
(
1980
,
4
,
23
),
reporter
=
r2
)
self
.
assertEqual
(
list
(
Article
.
objects
.
select_related
()
.
dates
(
'pub_date'
,
'day'
)),
self
.
assertEqual
(
[
list
(
Article
.
objects
.
select_related
()
.
dates
(
'pub_date'
,
'day'
)),
datetime
.
date
(
1980
,
4
,
23
),
[
datetime
.
date
(
1980
,
4
,
23
),
datetime
.
date
(
2005
,
7
,
27
)]
datetime
.
date
(
2005
,
7
,
27
),
)
])
self
.
assertEqual
(
self
.
assertEqual
(
list
(
Article
.
objects
.
select_related
()
.
dates
(
'pub_date'
,
'month'
)),
list
(
Article
.
objects
.
select_related
()
.
dates
(
'pub_date'
,
'month'
)),
[
[
datetime
.
date
(
1980
,
4
,
1
),
datetime
.
date
(
2005
,
7
,
1
)]
datetime
.
date
(
1980
,
4
,
1
),
)
datetime
.
date
(
2005
,
7
,
1
),
self
.
assertEqual
(
])
list
(
Article
.
objects
.
select_related
()
.
dates
(
'pub_date'
,
'year'
)),
self
.
assertEqual
(
list
(
Article
.
objects
.
select_related
()
.
dates
(
'pub_date'
,
'year'
)),
[
datetime
.
date
(
1980
,
1
,
1
),
datetime
.
date
(
2005
,
1
,
1
)]
[
)
datetime
.
date
(
1980
,
1
,
1
),
datetime
.
date
(
2005
,
1
,
1
),
])
def
test_delete
(
self
):
def
test_delete
(
self
):
self
.
r
.
article_set
.
create
(
headline
=
"John's second story"
,
self
.
r
.
article_set
.
create
(
headline
=
"John's second story"
,
pub_date
=
datetime
.
date
(
2005
,
7
,
29
))
pub_date
=
datetime
.
date
(
2005
,
7
,
29
))
self
.
r2
.
article_set
.
create
(
headline
=
"Paul's story"
,
pub_date
=
datetime
.
date
(
2006
,
1
,
17
))
self
.
r2
.
article_set
.
create
(
headline
=
"Paul's story"
,
Article
.
objects
.
create
(
headline
=
"Third article"
,
pub_date
=
datetime
.
date
(
2005
,
7
,
27
),
reporter_id
=
self
.
r
.
id
)
pub_date
=
datetime
.
date
(
2006
,
1
,
17
))
Article
.
objects
.
create
(
Article
.
objects
.
create
(
id
=
None
,
headline
=
"Third
article"
,
headline
=
"Fourth
article"
,
pub_date
=
datetime
.
date
(
2005
,
7
,
27
),
reporter_id
=
self
.
r
.
id
)
pub_date
=
datetime
.
date
(
2005
,
7
,
27
),
Article
.
objects
.
create
(
id
=
None
,
headline
=
"Fourth article"
,
reporter_id
=
str
(
self
.
r
.
id
)
,
pub_date
=
datetime
.
date
(
2005
,
7
,
27
),
reporter_id
=
str
(
self
.
r
.
id
)
)
)
# If you delete a reporter, his articles will be deleted.
# If you delete a reporter, his articles will be deleted.
self
.
assertQuerysetEqual
(
Article
.
objects
.
all
(),
self
.
assertQuerysetEqual
(
Article
.
objects
.
all
(),
[
[
"<Article: Fourth article>"
,
"<Article: Fourth article>"
,
"<Article: John's second story>"
,
"<Article: John's second story>"
,
"<Article: Paul's story>"
,
"<Article: Paul's story>"
,
"<Article: Third article>"
,
"<Article: Third article>"
,
"<Article: This is a test>"
,
"<Article: This is a test>"
,
]
)
]
self
.
assertQuerysetEqual
(
Reporter
.
objects
.
order_by
(
'first_name'
),
)
[
self
.
assertQuerysetEqual
(
"<Reporter: John Smith>"
,
Reporter
.
objects
.
order_by
(
'first_name'
)
,
"<Reporter: Paul Jones>"
,
[
"<Reporter: John Smith>"
,
"<Reporter: Paul Jones>"
]
]
)
)
self
.
r2
.
delete
()
self
.
r2
.
delete
()
self
.
assertQuerysetEqual
(
Article
.
objects
.
all
(),
self
.
assertQuerysetEqual
(
Article
.
objects
.
all
(),
[
[
"<Article: Fourth article>"
,
"<Article: Fourth article>"
,
"<Article: John's second story>"
,
"<Article: John's second story>"
,
"<Article: Third article>"
,
"<Article: Third article>"
,
"<Article: This is a test>"
,
"<Article: This is a test>"
,
]
)
]
self
.
assertQuerysetEqual
(
Reporter
.
objects
.
order_by
(
'first_name'
),
)
[
"<Reporter: John Smith>"
])
self
.
assertQuerysetEqual
(
Reporter
.
objects
.
order_by
(
'first_name'
),
[
"<Reporter: John Smith>"
])
# You can delete using a JOIN in the query.
# You can delete using a JOIN in the query.
Reporter
.
objects
.
filter
(
article__headline__startswith
=
'This'
)
.
delete
()
Reporter
.
objects
.
filter
(
article__headline__startswith
=
'This'
)
.
delete
()
self
.
assertQuerysetEqual
(
Reporter
.
objects
.
all
(),
[])
self
.
assertQuerysetEqual
(
Reporter
.
objects
.
all
(),
[])
...
@@ -433,33 +389,35 @@ class ManyToOneTests(TestCase):
...
@@ -433,33 +389,35 @@ class ManyToOneTests(TestCase):
def
test_explicit_fk
(
self
):
def
test_explicit_fk
(
self
):
# Create a new Article with get_or_create using an explicit value
# Create a new Article with get_or_create using an explicit value
# for a ForeignKey.
# for a ForeignKey.
a2
,
created
=
Article
.
objects
.
get_or_create
(
id
=
None
,
a2
,
created
=
Article
.
objects
.
get_or_create
(
headline
=
"John's second test"
,
headline
=
"John's second test"
,
pub_date
=
datetime
.
date
(
2011
,
5
,
7
),
pub_date
=
datetime
.
date
(
2011
,
5
,
7
),
reporter_id
=
self
.
r
.
id
)
reporter_id
=
self
.
r
.
id
,
)
self
.
assertTrue
(
created
)
self
.
assertTrue
(
created
)
self
.
assertEqual
(
a2
.
reporter
.
id
,
self
.
r
.
id
)
self
.
assertEqual
(
a2
.
reporter
.
id
,
self
.
r
.
id
)
# You can specify filters containing the explicit FK value.
# You can specify filters containing the explicit FK value.
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
Article
.
objects
.
filter
(
reporter_id__exact
=
self
.
r
.
id
),
Article
.
objects
.
filter
(
reporter_id__exact
=
self
.
r
.
id
),
[
[
"<Article: John's second test>"
,
"<Article: This is a test>"
]
"<Article: John's second test>"
,
)
"<Article: This is a test>"
,
])
# Create an Article by Paul for the same date.
# Create an Article by Paul for the same date.
a3
=
Article
.
objects
.
create
(
id
=
None
,
headline
=
"Paul's commentary"
,
a3
=
Article
.
objects
.
create
(
headline
=
"Paul's commentary"
,
pub_date
=
datetime
.
date
(
2011
,
5
,
7
),
pub_date
=
datetime
.
date
(
2011
,
5
,
7
),
reporter_id
=
self
.
r2
.
id
)
reporter_id
=
self
.
r2
.
id
,
)
self
.
assertEqual
(
a3
.
reporter
.
id
,
self
.
r2
.
id
)
self
.
assertEqual
(
a3
.
reporter
.
id
,
self
.
r2
.
id
)
# Get should respect explicit foreign keys as well.
# Get should respect explicit foreign keys as well.
with
self
.
assertRaises
(
MultipleObjectsReturned
):
with
self
.
assertRaises
(
MultipleObjectsReturned
):
Article
.
objects
.
get
(
reporter_id
=
self
.
r
.
id
)
Article
.
objects
.
get
(
reporter_id
=
self
.
r
.
id
)
self
.
assertEqual
(
repr
(
a3
),
self
.
assertEqual
(
repr
(
Article
.
objects
.
get
(
reporter_id
=
self
.
r2
.
id
,
repr
(
a3
),
pub_date
=
datetime
.
date
(
2011
,
5
,
7
))))
repr
(
Article
.
objects
.
get
(
reporter_id
=
self
.
r2
.
id
,
pub_date
=
datetime
.
date
(
2011
,
5
,
7
)))
)
def
test_deepcopy_and_circular_references
(
self
):
def
test_deepcopy_and_circular_references
(
self
):
# Regression for #12876 -- Model methods that include queries that
# Regression for #12876 -- Model methods that include queries that
...
@@ -478,12 +436,9 @@ class ManyToOneTests(TestCase):
...
@@ -478,12 +436,9 @@ class ManyToOneTests(TestCase):
self
.
assertIs
(
r1
.
article_set
.
__class__
,
r2
.
article_set
.
__class__
)
self
.
assertIs
(
r1
.
article_set
.
__class__
,
r2
.
article_set
.
__class__
)
def
test_create_relation_with_ugettext_lazy
(
self
):
def
test_create_relation_with_ugettext_lazy
(
self
):
reporter
=
Reporter
.
objects
.
create
(
first_name
=
'John'
,
reporter
=
Reporter
.
objects
.
create
(
first_name
=
'John'
,
last_name
=
'Smith'
,
email
=
'john.smith@example.com'
)
last_name
=
'Smith'
,
email
=
'john.smith@example.com'
)
lazy
=
ugettext_lazy
(
'test'
)
lazy
=
ugettext_lazy
(
'test'
)
reporter
.
article_set
.
create
(
headline
=
lazy
,
reporter
.
article_set
.
create
(
headline
=
lazy
,
pub_date
=
datetime
.
date
(
2011
,
6
,
10
))
pub_date
=
datetime
.
date
(
2011
,
6
,
10
))
notlazy
=
six
.
text_type
(
lazy
)
notlazy
=
six
.
text_type
(
lazy
)
article
=
reporter
.
article_set
.
get
()
article
=
reporter
.
article_set
.
get
()
self
.
assertEqual
(
article
.
headline
,
notlazy
)
self
.
assertEqual
(
article
.
headline
,
notlazy
)
...
@@ -632,10 +587,7 @@ class ManyToOneTests(TestCase):
...
@@ -632,10 +587,7 @@ class ManyToOneTests(TestCase):
private_student
=
Student
.
objects
.
create
(
school
=
private_school
)
private_student
=
Student
.
objects
.
create
(
school
=
private_school
)
# Only one school is available via all() due to the custom default manager.
# Only one school is available via all() due to the custom default manager.
self
.
assertQuerysetEqual
(
self
.
assertQuerysetEqual
(
School
.
objects
.
all
(),
[
"<School: School object>"
])
School
.
objects
.
all
(),
[
"<School: School object>"
]
)
self
.
assertEqual
(
public_student
.
school
,
public_school
)
self
.
assertEqual
(
public_student
.
school
,
public_school
)
...
...
tests/middleware/test_security.py
Dosyayı görüntüle @
406675b1
...
@@ -86,10 +86,7 @@ class SecurityMiddlewareTest(SimpleTestCase):
...
@@ -86,10 +86,7 @@ class SecurityMiddlewareTest(SimpleTestCase):
"includeSubDomains" tag to the response.
"includeSubDomains" tag to the response.
"""
"""
response
=
self
.
process_response
(
secure
=
True
)
response
=
self
.
process_response
(
secure
=
True
)
self
.
assertEqual
(
self
.
assertEqual
(
response
[
"strict-transport-security"
],
"max-age=600; includeSubDomains"
)
response
[
"strict-transport-security"
],
"max-age=600; includeSubDomains"
,
)
@override_settings
(
@override_settings
(
SECURE_HSTS_SECONDS
=
600
,
SECURE_HSTS_INCLUDE_SUBDOMAINS
=
False
)
SECURE_HSTS_SECONDS
=
600
,
SECURE_HSTS_INCLUDE_SUBDOMAINS
=
False
)
...
...
tests/migrations/test_writer.py
Dosyayı görüntüle @
406675b1
tests/template_tests/test_response.py
Dosyayı görüntüle @
406675b1
...
@@ -270,7 +270,8 @@ class TemplateResponseTest(SimpleTestCase):
...
@@ -270,7 +270,8 @@ class TemplateResponseTest(SimpleTestCase):
def
test_pickling
(
self
):
def
test_pickling
(
self
):
# Create a template response. The context is
# Create a template response. The context is
# known to be unpicklable (e.g., a function).
# known to be unpicklable (e.g., a function).
response
=
TemplateResponse
(
self
.
factory
.
get
(
'/'
),
response
=
TemplateResponse
(
self
.
factory
.
get
(
'/'
),
'first/test.html'
,
{
'first/test.html'
,
{
'value'
:
123
,
'value'
:
123
,
'fn'
:
datetime
.
now
,
'fn'
:
datetime
.
now
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment