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
6c9f37ea
Kaydet (Commit)
6c9f37ea
authored
Eki 01, 2015
tarafından
Simon Charette
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Fixed #18012 -- Propagated reverse foreign keys from proxy to concrete models.
Thanks to Anssi for the review.
üst
c8f091f5
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
36 additions
and
14 deletions
+36
-14
related.py
django/db/models/fields/related.py
+1
-1
related_descriptors.py
django/db/models/fields/related_descriptors.py
+1
-1
options.py
django/db/models/options.py
+10
-3
1.10.txt
docs/releases/1.10.txt
+5
-1
models.py
tests/model_meta/models.py
+1
-1
results.py
tests/model_meta/results.py
+6
-0
models.py
tests/proxy_models/models.py
+1
-1
tests.py
tests/proxy_models/tests.py
+11
-6
No files found.
django/db/models/fields/related.py
Dosyayı görüntüle @
6c9f37ea
...
...
@@ -684,7 +684,7 @@ class ForeignObject(RelatedField):
# Internal FK's - i.e., those with a related name ending with '+' -
# and swapped models don't get a related descriptor.
if
not
self
.
remote_field
.
is_hidden
()
and
not
related
.
related_model
.
_meta
.
swapped
:
setattr
(
cls
,
related
.
get_accessor_name
(),
self
.
related_accessor_class
(
related
))
setattr
(
cls
.
_meta
.
concrete_model
,
related
.
get_accessor_name
(),
self
.
related_accessor_class
(
related
))
# While 'limit_choices_to' might be a callable, simply pass
# it along for later - this is too early because it's still
# model load time.
...
...
django/db/models/fields/related_descriptors.py
Dosyayı görüntüle @
6c9f37ea
...
...
@@ -198,7 +198,7 @@ class ForwardManyToOneDescriptor(object):
'Cannot assign None: "
%
s.
%
s" does not allow null values.'
%
(
instance
.
_meta
.
object_name
,
self
.
field
.
name
)
)
elif
value
is
not
None
and
not
isinstance
(
value
,
self
.
field
.
remote_field
.
model
):
elif
value
is
not
None
and
not
isinstance
(
value
,
self
.
field
.
remote_field
.
model
.
_meta
.
concrete_model
):
raise
ValueError
(
'Cannot assign "
%
r": "
%
s.
%
s" must be a "
%
s" instance.'
%
(
value
,
...
...
django/db/models/options.py
Dosyayı görüntüle @
6c9f37ea
...
...
@@ -552,15 +552,20 @@ class Options(object):
is set as a property on every model.
"""
related_objects_graph
=
defaultdict
(
list
)
# Map of concrete models to all options of models it represents.
# Including its options and all its proxy model ones.
concrete_model_classes
=
defaultdict
(
list
)
all_models
=
self
.
apps
.
get_models
(
include_auto_created
=
True
)
for
model
in
all_models
:
opts
=
model
.
_meta
concrete_model_classes
[
opts
.
concrete_model
]
.
append
(
opts
)
# Abstract model's fields are copied to child models, hence we will
# see the fields from the child models.
if
model
.
_meta
.
abstract
:
if
opts
.
abstract
:
continue
fields_with_relations
=
(
f
for
f
in
model
.
_meta
.
_get_fields
(
reverse
=
False
,
include_parents
=
False
)
f
for
f
in
opts
.
_get_fields
(
reverse
=
False
,
include_parents
=
False
)
if
f
.
is_relation
and
f
.
related_model
is
not
None
)
for
f
in
fields_with_relations
:
...
...
@@ -573,7 +578,9 @@ class Options(object):
# __dict__ takes precedence over a data descriptor (such as
# @cached_property). This means that the _meta._relation_tree is
# only called if related_objects is not in __dict__.
related_objects
=
related_objects_graph
[
model
.
_meta
]
related_objects
=
list
(
chain
.
from_iterable
(
related_objects_graph
[
opts
]
for
opts
in
concrete_model_classes
[
model
]
))
model
.
_meta
.
__dict__
[
'_relation_tree'
]
=
related_objects
# It seems it is possible that self is not in all_models, so guard
# against that with default for get().
...
...
docs/releases/1.10.txt
Dosyayı görüntüle @
6c9f37ea
...
...
@@ -163,7 +163,11 @@ Migrations
Models
^^^^^^
* ...
* Reverse foreign keys from proxy models are now propagated to their
concrete class. The reverse relation attached by a
:class:`~django.db.models.ForeignKey` pointing to a proxy model is now
accessible as a descriptor on the proxied model class and may be referenced in
queryset filtering.
Requests and Responses
^^^^^^^^^^^^^^^^^^^^^^
...
...
tests/model_meta/models.py
Dosyayı görüntüle @
6c9f37ea
...
...
@@ -113,7 +113,7 @@ class Relating(models.Model):
# ForeignKey to ProxyPerson
proxyperson
=
models
.
ForeignKey
(
ProxyPerson
,
models
.
CASCADE
,
related_name
=
'relating_proxyperson'
)
proxyperson_hidden
=
models
.
ForeignKey
(
ProxyPerson
,
models
.
CASCADE
,
related_name
=
'+'
)
proxyperson_hidden
=
models
.
ForeignKey
(
ProxyPerson
,
models
.
CASCADE
,
related_name
=
'
relating_proxyperson_hidden
+'
)
# ManyToManyField to BasePerson
basepeople
=
models
.
ManyToManyField
(
BasePerson
,
related_name
=
'relating_basepeople'
)
...
...
tests/model_meta/results.py
Dosyayı görüntüle @
6c9f37ea
...
...
@@ -331,6 +331,8 @@ TEST_RESULTS = {
(
'friends_inherited_rel_+'
,
None
),
(
'relating_people'
,
None
),
(
'relating_person'
,
None
),
(
'relating_proxyperson'
,
None
),
(
'relating_proxyperson_hidden+'
,
None
),
),
BasePerson
:
(
(
'+'
,
None
),
...
...
@@ -413,6 +415,8 @@ TEST_RESULTS = {
(
'relating_baseperson'
,
BasePerson
),
(
'relating_people'
,
None
),
(
'relating_person'
,
None
),
(
'relating_proxyperson'
,
None
),
(
'relating_proxyperson_hidden+'
,
None
),
),
BasePerson
:
(
(
'+'
,
None
),
...
...
@@ -465,6 +469,7 @@ TEST_RESULTS = {
(
'followers_concrete'
,
None
),
(
'relating_person'
,
None
),
(
'relating_people'
,
None
),
(
'relating_proxyperson'
,
None
),
),
BasePerson
:
(
(
'followers_abstract'
,
None
),
...
...
@@ -494,6 +499,7 @@ TEST_RESULTS = {
(
'followers_concrete'
,
None
),
(
'relating_person'
,
None
),
(
'relating_people'
,
None
),
(
'relating_proxyperson'
,
None
),
),
BasePerson
:
(
(
'followers_abstract'
,
None
),
...
...
tests/proxy_models/models.py
Dosyayı görüntüle @
6c9f37ea
...
...
@@ -158,7 +158,7 @@ class ProxyTrackerUser(TrackerUser):
@python_2_unicode_compatible
class
Issue
(
models
.
Model
):
summary
=
models
.
CharField
(
max_length
=
255
)
assignee
=
models
.
ForeignKey
(
ProxyTrackerUser
,
models
.
CASCADE
)
assignee
=
models
.
ForeignKey
(
ProxyTrackerUser
,
models
.
CASCADE
,
related_name
=
'issues'
)
def
__str__
(
self
):
return
':'
.
join
((
self
.
__class__
.
__name__
,
self
.
summary
,))
...
...
tests/proxy_models/tests.py
Dosyayı görüntüle @
6c9f37ea
...
...
@@ -6,7 +6,7 @@ from django.apps import apps
from
django.contrib
import
admin
from
django.contrib.auth.models
import
User
as
AuthUser
from
django.contrib.contenttypes.models
import
ContentType
from
django.core
import
checks
,
exceptions
,
management
from
django.core
import
checks
,
management
from
django.core.urlresolvers
import
reverse
from
django.db
import
DEFAULT_DB_ALIAS
,
models
from
django.db.models
import
signals
...
...
@@ -332,14 +332,19 @@ class ProxyModelTests(TestCase):
self
.
assertEqual
(
resp
.
name
,
'New South Wales'
)
def
test_filter_proxy_relation_reverse
(
self
):
tu
=
TrackerUser
.
objects
.
create
(
name
=
'Contributor'
,
status
=
'contrib'
)
with
self
.
assertRaises
(
exceptions
.
FieldError
):
TrackerUser
.
objects
.
filter
(
issue
=
None
),
tu
=
TrackerUser
.
objects
.
create
(
name
=
'Contributor'
,
status
=
'contrib'
)
ptu
=
ProxyTrackerUser
.
objects
.
get
()
issue
=
Issue
.
objects
.
create
(
assignee
=
tu
)
self
.
assertEqual
(
tu
.
issues
.
get
(),
issue
)
self
.
assertEqual
(
ptu
.
issues
.
get
(),
issue
)
self
.
assertQuerysetEqual
(
ProxyTrackerUser
.
objects
.
filter
(
issue
=
Non
e
),
TrackerUser
.
objects
.
filter
(
issues
=
issu
e
),
[
tu
],
lambda
x
:
x
)
self
.
assertQuerysetEqual
(
ProxyTrackerUser
.
objects
.
filter
(
issues
=
issue
),
[
ptu
],
lambda
x
:
x
)
def
test_proxy_bug
(
self
):
contributor
=
ProxyTrackerUser
.
objects
.
create
(
name
=
'Contributor'
,
...
...
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