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
b84f5ab4
Kaydet (Commit)
b84f5ab4
authored
Şub 24, 2016
tarafından
chenesan
Kaydeden (comit)
Tim Graham
Şub 27, 2016
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Fixed #26230 -- Made default_related_name affect related_query_name.
üst
5fb9756e
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
97 additions
and
8 deletions
+97
-8
related.py
django/db/models/fields/related.py
+6
-1
reverse_related.py
django/db/models/fields/reverse_related.py
+0
-5
query.py
django/db/models/sql/query.py
+15
-0
deprecation.txt
docs/internals/deprecation.txt
+3
-0
fields.txt
docs/ref/models/fields.txt
+3
-2
options.txt
docs/ref/models/options.txt
+26
-0
1.10.txt
docs/releases/1.10.txt
+28
-0
test_default_related_name.py
tests/model_options/test_default_related_name.py
+16
-0
No files found.
django/db/models/fields/related.py
Dosyayı görüntüle @
b84f5ab4
...
...
@@ -290,8 +290,13 @@ class RelatedField(Field):
if
not
cls
.
_meta
.
abstract
:
if
self
.
remote_field
.
related_name
:
related_name
=
force_text
(
self
.
remote_field
.
related_name
)
%
{
related_name
=
self
.
remote_field
.
related_name
else
:
related_name
=
self
.
opts
.
default_related_name
if
related_name
:
related_name
=
force_text
(
related_name
)
%
{
'class'
:
cls
.
__name__
.
lower
(),
'model_name'
:
cls
.
_meta
.
model_name
.
lower
(),
'app_label'
:
cls
.
_meta
.
app_label
.
lower
()
}
self
.
remote_field
.
related_name
=
related_name
...
...
django/db/models/fields/reverse_related.py
Dosyayı görüntüle @
b84f5ab4
...
...
@@ -187,11 +187,6 @@ class ForeignObjectRel(object):
return
None
if
self
.
related_name
:
return
self
.
related_name
if
opts
.
default_related_name
:
return
opts
.
default_related_name
%
{
'model_name'
:
opts
.
model_name
.
lower
(),
'app_label'
:
opts
.
app_label
.
lower
(),
}
return
opts
.
model_name
+
(
'_set'
if
self
.
multiple
else
''
)
def
get_cache_name
(
self
):
...
...
django/db/models/sql/query.py
Dosyayı görüntüle @
b84f5ab4
...
...
@@ -7,6 +7,7 @@ databases). The abstraction barrier only works one way: this module has to know
all about the internals of models in order to get the information it needs.
"""
import
copy
import
warnings
from
collections
import
Counter
,
Iterator
,
Mapping
,
OrderedDict
from
itertools
import
chain
,
count
,
product
from
string
import
ascii_uppercase
...
...
@@ -30,6 +31,7 @@ from django.db.models.sql.where import (
AND
,
OR
,
ExtraWhere
,
NothingNode
,
WhereNode
,
)
from
django.utils
import
six
from
django.utils.deprecation
import
RemovedInDjango20Warning
from
django.utils.encoding
import
force_text
from
django.utils.tree
import
Node
...
...
@@ -1288,6 +1290,19 @@ class Query(object):
except
FieldDoesNotExist
:
if
name
in
self
.
annotation_select
:
field
=
self
.
annotation_select
[
name
]
.
output_field
elif
pos
==
0
:
for
rel
in
opts
.
related_objects
:
if
(
name
==
rel
.
related_model
.
_meta
.
model_name
and
rel
.
related_name
==
rel
.
related_model
.
_meta
.
default_related_name
):
related_name
=
rel
.
related_name
field
=
opts
.
get_field
(
related_name
)
warnings
.
warn
(
"Query lookup '
%
s' is deprecated in favor of "
"Meta.default_related_name '
%
s'."
%
(
name
,
related_name
),
RemovedInDjango20Warning
,
2
)
break
if
field
is
not
None
:
# Fields that contain one-to-many relations with a generic
...
...
docs/internals/deprecation.txt
Dosyayı görüntüle @
b84f5ab4
...
...
@@ -138,6 +138,9 @@ details on these changes.
* Support for the ``django.core.files.storage.Storage.accessed_time()``,
``created_time()``, and ``modified_time()`` methods will be removed.
* Support for query lookups using the model name when
``Meta.default_related_name`` is set will be removed.
.. _deprecation-removed-in-1.10:
1.10
...
...
docs/ref/models/fields.txt
Dosyayı görüntüle @
b84f5ab4
...
...
@@ -1333,8 +1333,9 @@ The possible values for :attr:`~ForeignKey.on_delete` are found in
.. attribute:: ForeignKey.related_query_name
The name to use for the reverse filter name from the target model.
Defaults to the value of :attr:`related_name` if it is set, otherwise it
The name to use for the reverse filter name from the target model. It
defaults to the value of :attr:`related_name` or
:attr:`~django.db.models.Options.default_related_name` if set, otherwise it
defaults to the name of the model::
# Declare the ForeignKey with related_query_name
...
...
docs/ref/models/options.txt
Dosyayı görüntüle @
b84f5ab4
...
...
@@ -103,6 +103,8 @@ Django quotes column and table names behind the scenes.
The name that will be used by default for the relation from a related object
back to this one. The default is ``<model_name>_set``.
This option also sets :attr:`~ForeignKey.related_query_name`.
As the reverse name for a field should be unique, be careful if you intend
to subclass your model. To work around name collisions, part of the name
should contain ``'%(app_label)s'`` and ``'%(model_name)s'``, which are
...
...
@@ -110,6 +112,30 @@ Django quotes column and table names behind the scenes.
and the name of the model, both lowercased. See the paragraph on
:ref:`related names for abstract models <abstract-related-name>`.
.. deprecated:: 1.10
This attribute now affects ``related_query_name``. The old query lookup
name is deprecated::
from django.db import models
class Foo(models.Model):
pass
class Bar(models.Model):
foo = models.ForeignKey(Foo)
class Meta:
default_related_name = 'bars'
::
>>> bar = Bar.objects.get(pk=1)
>>> # Using model name "bar" as lookup string is deprecated.
>>> Foo.object.get(bar=bar)
>>> # You should use default_related_name "bars".
>>> Foo.object.get(bars=bar)
``get_latest_by``
-----------------
...
...
docs/releases/1.10.txt
Dosyayı görüntüle @
b84f5ab4
...
...
@@ -704,6 +704,34 @@ longer than the 4000 byte limit of ``NVARCHAR2``, you should use ``TextField``
field (e.g. annotating the model with an aggregation or using ``distinct()``)
you'll need to change them (to defer the field).
Using a model name as a query lookup when ``default_related_name`` is set
-------------------------------------------------------------------------
Assume the following models::
from django.db import models
class Foo(models.Model):
pass
class Bar(models.Model):
foo = models.ForeignKey(Foo)
class Meta:
default_related_name = 'bars'
In older versions, :attr:`~django.db.models.Options.default_related_name`
couldn't be used as a query lookup. This is fixed and support for the old
lookup name is deprecated. For example, since ``default_related_name`` is set
in model ``Bar``, instead of using the model name ``bar`` as the lookup::
>>> bar = Bar.objects.get(pk=1)
>>> Foo.object.get(bar=bar)
use the default_related_name ``bars``::
>>> Foo.object.get(bars=bar)
Miscellaneous
-------------
...
...
tests/model_options/test_default_related_name.py
Dosyayı görüntüle @
b84f5ab4
import
warnings
from
django.test
import
TestCase
from
django.utils.deprecation
import
RemovedInDjango20Warning
from
.models.default_related_name
import
Author
,
Book
,
Editor
...
...
@@ -18,6 +21,19 @@ class DefaultRelatedNameTests(TestCase):
def
test_default_related_name
(
self
):
self
.
assertEqual
(
list
(
self
.
author
.
books
.
all
()),
[
self
.
book
])
def
test_default_related_name_in_queryset_lookup
(
self
):
self
.
assertEqual
(
Author
.
objects
.
get
(
books
=
self
.
book
),
self
.
author
)
def
test_show_deprecated_message_when_model_name_in_queryset_lookup
(
self
):
msg
=
"Query lookup 'book' is deprecated in favor of Meta.default_related_name 'books'."
with
warnings
.
catch_warnings
(
record
=
True
)
as
warns
:
warnings
.
simplefilter
(
'once'
)
Author
.
objects
.
get
(
book
=
self
.
book
)
self
.
assertEqual
(
len
(
warns
),
1
)
warning
=
warns
.
pop
()
self
.
assertEqual
(
warning
.
category
,
RemovedInDjango20Warning
)
self
.
assertEqual
(
str
(
warning
.
message
),
msg
)
def
test_related_name_overrides_default_related_name
(
self
):
self
.
assertEqual
(
list
(
self
.
editor
.
edited_books
.
all
()),
[
self
.
book
])
...
...
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