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
5efd4721
Kaydet (Commit)
5efd4721
authored
Şub 16, 2015
tarafından
Loic Bistuer
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Reworked docstrings and comments in related.py.
Thanks Tim Graham for the review.
üst
c5a77721
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
199 additions
and
85 deletions
+199
-85
fields.py
django/contrib/contenttypes/fields.py
+32
-24
related.py
django/db/models/fields/related.py
+167
-61
No files found.
django/contrib/contenttypes/fields.py
Dosyayı görüntüle @
5efd4721
...
...
@@ -19,9 +19,14 @@ from django.utils.functional import cached_property
@python_2_unicode_compatible
class
GenericForeignKey
(
object
):
"""
Provides a generic relation to any object through content-type/object-id
fields.
Provide a generic many-to-one relation through the ``content_type`` and
``object_id`` fields.
This class also doubles as an accessor to the related object (similar to
ReverseSingleRelatedObjectDescriptor) by adding itself as a model
attribute.
"""
# Field flags
auto_created
=
False
concrete
=
False
...
...
@@ -96,9 +101,10 @@ class GenericForeignKey(object):
return
[]
def
_check_content_type_field
(
self
):
""" Check if field named `field_name` in model `model` exists and is
valid content_type field (is a ForeignKey to ContentType). """
"""
Check if field named `field_name` in model `model` exists and is a
valid content_type field (is a ForeignKey to ContentType).
"""
try
:
field
=
self
.
model
.
_meta
.
get_field
(
self
.
ct_field
)
except
FieldDoesNotExist
:
...
...
@@ -146,8 +152,8 @@ class GenericForeignKey(object):
def
instance_pre_init
(
self
,
signal
,
sender
,
args
,
kwargs
,
**
_kwargs
):
"""
Handle
s
initializing an object with the generic FK instead of
content
-type/object-
id fields.
Handle initializing an object with the generic FK instead of
content
_type and object_
id fields.
"""
if
self
.
name
in
kwargs
:
value
=
kwargs
.
pop
(
self
.
name
)
...
...
@@ -256,6 +262,10 @@ class GenericForeignKey(object):
class
GenericRel
(
ForeignObjectRel
):
"""
Used by GenericRelation to store information about the relation.
"""
def
__init__
(
self
,
field
,
to
,
related_name
=
None
,
related_query_name
=
None
,
limit_choices_to
=
None
):
super
(
GenericRel
,
self
)
.
__init__
(
field
,
to
,
...
...
@@ -267,7 +277,10 @@ class GenericRel(ForeignObjectRel):
class
GenericRelation
(
ForeignObject
):
"""Provides an accessor to generic related objects (e.g. comments)"""
"""
Provide a reverse to a relation created by a GenericForeignKey.
"""
# Field flags
auto_created
=
False
...
...
@@ -310,9 +323,6 @@ class GenericRelation(ForeignObject):
def
_check_generic_foreign_key_existence
(
self
):
target
=
self
.
rel
.
to
if
isinstance
(
target
,
ModelBase
):
# Using `vars` is very ugly approach, but there is no better one,
# because GenericForeignKeys are not considered as fields and,
# therefore, are not included in `target._meta.local_fields`.
fields
=
target
.
_meta
.
virtual_fields
if
any
(
isinstance
(
field
,
GenericForeignKey
)
and
field
.
ct_field
==
self
.
content_type_field_name
and
...
...
@@ -358,9 +368,7 @@ class GenericRelation(ForeignObject):
def
contribute_to_class
(
self
,
cls
,
name
,
**
kwargs
):
kwargs
[
'virtual_only'
]
=
True
super
(
GenericRelation
,
self
)
.
contribute_to_class
(
cls
,
name
,
**
kwargs
)
# Save a reference to which model this class is on for future use
self
.
model
=
cls
# Add the descriptor for the relation
setattr
(
cls
,
self
.
name
,
ReverseGenericRelatedObjectsDescriptor
(
self
.
rel
))
def
set_attributes_from_rel
(
self
):
...
...
@@ -371,7 +379,7 @@ class GenericRelation(ForeignObject):
def
get_content_type
(
self
):
"""
Return
s
the content type associated with this field's model.
Return the content type associated with this field's model.
"""
return
ContentType
.
objects
.
get_for_model
(
self
.
model
,
for_concrete_model
=
self
.
for_concrete_model
)
...
...
@@ -387,7 +395,6 @@ class GenericRelation(ForeignObject):
def
bulk_related_objects
(
self
,
objs
,
using
=
DEFAULT_DB_ALIAS
):
"""
Return all objects related to ``objs`` via this ``GenericRelation``.
"""
return
self
.
rel
.
to
.
_base_manager
.
db_manager
(
using
)
.
filter
(
**
{
"
%
s__pk"
%
self
.
content_type_field_name
:
ContentType
.
objects
.
db_manager
(
using
)
.
get_for_model
(
...
...
@@ -398,16 +405,16 @@ class GenericRelation(ForeignObject):
class
ReverseGenericRelatedObjectsDescriptor
(
ForeignRelatedObjectsDescriptor
):
"""
This class provides the functionality that makes the related-object
managers available as attributes on a model class, for fields that have
multiple "remote" values and have a GenericRelation defined in their model
(rather than having another model pointed *at* them). In the example
"article.publications", the publications attribute is a
ReverseGenericRelatedObjectsDescriptor instance.
"""
Accessor to the related objects manager on the one-to-many relation created
by GenericRelation.
In the example::
class Post(Model):
comments = GenericRelation(Comment)
``post.comments`` is a ReverseGenericRelatedObjectsDescriptor instance.
"""
@cached_property
def
related_manager_cls
(
self
):
...
...
@@ -419,8 +426,9 @@ class ReverseGenericRelatedObjectsDescriptor(ForeignRelatedObjectsDescriptor):
def
create_generic_related_manager
(
superclass
,
rel
):
"""
Factory function for a manager that subclasses 'superclass' (which is a
Manager) and adds behavior for generic related objects.
Factory function to create a manager that subclasses another manager
(generally the default manager of a given model) and adds behaviors
specific to generic relations.
"""
class
GenericRelatedObjectManager
(
superclass
):
...
...
django/db/models/fields/related.py
Dosyayı görüntüle @
5efd4721
...
...
@@ -50,7 +50,8 @@ def add_lazy_relation(cls, field, relation, operation):
lazy relationships -- then the relation won't be set up until the
class_prepared signal fires at the end of model initialization.
operation is the work that must be performed once the relation can be resolved.
``operation`` is the work that must be performed once the relation can be
resolved.
"""
# Check for recursive relations
if
relation
==
RECURSIVE_RELATIONSHIP_CONSTANT
:
...
...
@@ -58,17 +59,17 @@ def add_lazy_relation(cls, field, relation, operation):
model_name
=
cls
.
__name__
else
:
# Look for an "app.Model" relation
# Look for an "app.Model" relation
.
if
isinstance
(
relation
,
six
.
string_types
):
try
:
app_label
,
model_name
=
relation
.
split
(
"."
)
except
ValueError
:
# If we can't split, assume a model in current app
# If we can't split, assume a model in current app
.
app_label
=
cls
.
_meta
.
app_label
model_name
=
relation
else
:
#
it's actually a model class
#
It's actually a model class.
app_label
=
relation
.
_meta
.
app_label
model_name
=
relation
.
_meta
.
object_name
...
...
@@ -88,7 +89,7 @@ def add_lazy_relation(cls, field, relation, operation):
def
do_pending_lookups
(
sender
,
**
kwargs
):
"""
Handle any pending relations to the sending model. Sent from class_prepared
.
Sent from class_prepared to handle pending relations to the sending model
.
"""
key
=
(
sender
.
_meta
.
app_label
,
sender
.
__name__
)
for
cls
,
field
,
operation
in
sender
.
_meta
.
apps
.
_pending_lookups
.
pop
(
key
,
[]):
...
...
@@ -98,6 +99,10 @@ signals.class_prepared.connect(do_pending_lookups)
class
RelatedField
(
Field
):
"""
Base class that all relational fields inherit from.
"""
# Field flags
one_to_many
=
False
one_to_one
=
False
...
...
@@ -174,8 +179,9 @@ class RelatedField(Field):
return
[]
def
_check_clashes
(
self
):
""" Check accessor and reverse query name clashes. """
"""
Check accessor and reverse query name clashes.
"""
from
django.db.models.base
import
ModelBase
errors
=
[]
...
...
@@ -278,14 +284,13 @@ class RelatedField(Field):
return
errors
def
db_type
(
self
,
connection
):
'''By default related field will not have a column
as it relates columns to another table'''
# By default related field will not have a column as it relates to
# columns from another table.
return
None
def
contribute_to_class
(
self
,
cls
,
name
,
virtual_only
=
False
):
sup
=
super
(
RelatedField
,
self
)
# Store the opts for related_query_name()
self
.
opts
=
cls
.
_meta
if
hasattr
(
sup
,
'contribute_to_class'
):
...
...
@@ -310,7 +315,7 @@ class RelatedField(Field):
@property
def
swappable_setting
(
self
):
"""
Get
s
the setting that this is powered from for swapping, or None
Get the setting that this is powered from for swapping, or None
if it's not swapped in / marked with swappable=False.
"""
if
self
.
swappable
:
...
...
@@ -350,7 +355,8 @@ class RelatedField(Field):
self
.
contribute_to_related_class
(
other
,
self
.
rel
)
def
get_limit_choices_to
(
self
):
"""Returns 'limit_choices_to' for this model field.
"""
Return ``limit_choices_to`` for this model field.
If it is a callable, it will be invoked and the result will be
returned.
...
...
@@ -360,7 +366,8 @@ class RelatedField(Field):
return
self
.
rel
.
limit_choices_to
def
formfield
(
self
,
**
kwargs
):
"""Passes ``limit_choices_to`` to field being constructed.
"""
Pass ``limit_choices_to`` to the field being constructed.
Only passes it if there is a type that supports related fields.
This is a similar strategy used to pass the ``queryset`` to the field
...
...
@@ -379,19 +386,26 @@ class RelatedField(Field):
return
super
(
RelatedField
,
self
)
.
formfield
(
**
defaults
)
def
related_query_name
(
self
):
# This method defines the name that can be used to identify this
# related object in a table-spanning query. It uses the lower-cased
# object_name by default, but this can be overridden with the
# "related_name" option.
"""
Define the name that can be used to identify this related object in a
table-spanning query.
"""
return
self
.
rel
.
related_query_name
or
self
.
rel
.
related_name
or
self
.
opts
.
model_name
class
SingleRelatedObjectDescriptor
(
object
):
# This class provides the functionality that makes the related-object
# managers available as attributes on a model class, for fields that have
# a single "remote" value, on the class pointed to by a related field.
# In the example "place.restaurant", the restaurant attribute is a
# SingleRelatedObjectDescriptor instance.
"""
Accessor to the related object on the reverse side of a one-to-one
relation.
In the example::
class Restaurant(Model):
place = OneToOneField(Place, related_name='restaurant')
``place.restaurant`` is a ``SingleRelatedObjectDescriptor`` instance.
"""
def
__init__
(
self
,
related
):
self
.
related
=
related
self
.
cache_name
=
related
.
get_cache_name
()
...
...
@@ -517,11 +531,18 @@ class SingleRelatedObjectDescriptor(object):
class
ReverseSingleRelatedObjectDescriptor
(
object
):
# This class provides the functionality that makes the related-object
# managers available as attributes on a model class, for fields that have
# a single "remote" value, on the class that defines the related field.
# In the example "choice.poll", the poll attribute is a
# ReverseSingleRelatedObjectDescriptor instance.
"""
Accessor to the related object on the forward side of a many-to-one or
one-to-one relation.
In the example::
class Choice(Model):
poll = ForeignKey(Place, related_name='choices')
`choice.poll` is a ReverseSingleRelatedObjectDescriptor instance.
"""
def
__init__
(
self
,
field_with_rel
):
self
.
field
=
field_with_rel
self
.
cache_name
=
self
.
field
.
get_cache_name
()
...
...
@@ -679,6 +700,12 @@ class ReverseSingleRelatedObjectDescriptor(object):
def
create_foreign_related_manager
(
superclass
,
rel
):
"""
Factory function to create a manager that subclasses another manager
(generally the default manager of a given model) and adds behaviors
specific to many-to-one relations.
"""
class
RelatedManager
(
superclass
):
def
__init__
(
self
,
instance
):
super
(
RelatedManager
,
self
)
.
__init__
()
...
...
@@ -833,11 +860,18 @@ def create_foreign_related_manager(superclass, rel):
class
ForeignRelatedObjectsDescriptor
(
object
):
# This class provides the functionality that makes the related-object
# managers available as attributes on a model class, for fields that have
# multiple "remote" values and have a ForeignKey pointed at them by
# some other model. In the example "poll.choice_set", the choice_set
# attribute is a ForeignRelatedObjectsDescriptor instance.
"""
Accessor to the related objects manager on the reverse side of a
many-to-one relation.
In the example::
class Choice(Model):
poll = ForeignKey(Place, related_name='choices')
``poll.choices`` is a ``ForeignRelatedObjectsDescriptor`` instance.
"""
def
__init__
(
self
,
rel
):
self
.
rel
=
rel
self
.
field
=
rel
.
field
...
...
@@ -861,9 +895,12 @@ class ForeignRelatedObjectsDescriptor(object):
def
create_many_related_manager
(
superclass
,
rel
,
reverse
):
"""
Factory function to create a manager that subclasses another manager
(generally the default manager of a given model) and adds behaviors
specific to many-to-many relations.
"""
"""Creates a manager that subclasses 'superclass' (which is a Manager)
and adds behavior for many-to-many related objects."""
class
ManyRelatedManager
(
superclass
):
def
__init__
(
self
,
instance
=
None
):
super
(
ManyRelatedManager
,
self
)
.
__init__
()
...
...
@@ -1198,9 +1235,18 @@ def create_many_related_manager(superclass, rel, reverse):
class
ManyRelatedObjectsDescriptor
(
ForeignRelatedObjectsDescriptor
):
"""
Accessor to the related objects manager on the forward and reverse sides of
a many-to-many relation.
In the example::
class Pizza(Model):
toppings = ManyToManyField(Topping, related_name='pizzas')
``pizza.toppings`` and ``topping.pizzas`` are ManyRelatedObjectsDescriptor
instances.
"""
def
__init__
(
self
,
rel
,
reverse
=
False
):
super
(
ManyRelatedObjectsDescriptor
,
self
)
.
__init__
(
rel
)
...
...
@@ -1217,8 +1263,6 @@ class ManyRelatedObjectsDescriptor(ForeignRelatedObjectsDescriptor):
@cached_property
def
related_manager_cls
(
self
):
model
=
self
.
rel
.
related_model
if
self
.
reverse
else
self
.
rel
.
to
# Dynamically create a class that subclasses the related model's
# default manager.
return
create_many_related_manager
(
model
.
_default_manager
.
__class__
,
self
.
rel
,
...
...
@@ -1227,7 +1271,12 @@ class ManyRelatedObjectsDescriptor(ForeignRelatedObjectsDescriptor):
class
ForeignObjectRel
(
object
):
"""
Used by ForeignObject to store information about the relation.
``_meta.get_fields()`` returns this class to provide access to the field
flags for the reverse relation.
"""
# Field flags
auto_created
=
True
...
...
@@ -1301,7 +1350,7 @@ class ForeignObjectRel(object):
def
get_choices
(
self
,
include_blank
=
True
,
blank_choice
=
BLANK_CHOICE_DASH
,
limit_to_currently_related
=
False
):
"""
Return
s
choices with a default blank choices included, for use as
Return choices with a default blank choices included, for use as
SelectField choices for this field.
Analog of django.db.models.fields.Field.get_choices(), provided
...
...
@@ -1370,6 +1419,20 @@ class ForeignObjectRel(object):
class
ManyToOneRel
(
ForeignObjectRel
):
"""
Used by the ForeignKey field to store information about the relation.
``_meta.get_fields()`` returns this class to provide access to the field
flags for the reverse relation.
Note: Because we somewhat abuse the Rel objects by using them as reverse
fields we get the funny situation where
``ManyToOneRel.many_to_one == False`` and
``ManyToOneRel.one_to_many == True``. This is unfortunate but the actual
ManyToOneRel class is a private API and there is work underway to turn
reverse relations into actual fields.
"""
def
__init__
(
self
,
field
,
to
,
field_name
,
related_name
=
None
,
related_query_name
=
None
,
limit_choices_to
=
None
,
parent_link
=
False
,
on_delete
=
None
):
super
(
ManyToOneRel
,
self
)
.
__init__
(
...
...
@@ -1385,8 +1448,7 @@ class ManyToOneRel(ForeignObjectRel):
def
get_related_field
(
self
):
"""
Returns the Field in the 'to' object to which this relationship is
tied.
Return the Field in the 'to' object to which this relationship is tied.
"""
field
=
self
.
to
.
_meta
.
get_field
(
self
.
field_name
)
if
not
field
.
concrete
:
...
...
@@ -1399,6 +1461,13 @@ class ManyToOneRel(ForeignObjectRel):
class
OneToOneRel
(
ManyToOneRel
):
"""
Used by OneToOneField to store information about the relation.
``_meta.get_fields()`` returns this class to provide access to the field
flags for the reverse relation.
"""
def
__init__
(
self
,
field
,
to
,
field_name
,
related_name
=
None
,
related_query_name
=
None
,
limit_choices_to
=
None
,
parent_link
=
False
,
on_delete
=
None
):
super
(
OneToOneRel
,
self
)
.
__init__
(
...
...
@@ -1414,6 +1483,13 @@ class OneToOneRel(ManyToOneRel):
class
ManyToManyRel
(
ForeignObjectRel
):
"""
Used by ManyToManyField to store information about the relation.
``_meta.get_fields()`` returns this class to provide access to the field
flags for the reverse relation.
"""
def
__init__
(
self
,
field
,
to
,
related_name
=
None
,
related_query_name
=
None
,
limit_choices_to
=
None
,
symmetrical
=
True
,
through
=
None
,
through_fields
=
None
,
db_constraint
=
True
):
...
...
@@ -1437,7 +1513,7 @@ class ManyToManyRel(ForeignObjectRel):
def
get_related_field
(
self
):
"""
Return
s
the field in the 'to' object to which this relationship is tied.
Return the field in the 'to' object to which this relationship is tied.
Provided for symmetry with ManyToOneRel.
"""
opts
=
self
.
through
.
_meta
...
...
@@ -1452,6 +1528,10 @@ class ManyToManyRel(ForeignObjectRel):
class
ForeignObject
(
RelatedField
):
"""
Abstraction of the ForeignKey relation, supports multi-column relations.
"""
# Field flags
many_to_many
=
False
many_to_one
=
True
...
...
@@ -1491,7 +1571,6 @@ class ForeignObject(RelatedField):
if
rel_is_string
or
not
self
.
requires_unique_target
:
return
[]
# Skip if the
try
:
self
.
foreign_related_fields
except
FieldDoesNotExist
:
...
...
@@ -1640,7 +1719,7 @@ class ForeignObject(RelatedField):
def
get_extra_descriptor_filter
(
self
,
instance
):
"""
Return
s
an extra filter condition for related object fetching when
Return an extra filter condition for related object fetching when
user does 'instance.fieldname', that is the extra filter is used in
the descriptor of the field.
...
...
@@ -1655,7 +1734,7 @@ class ForeignObject(RelatedField):
def
get_extra_restriction
(
self
,
where_class
,
alias
,
related_alias
):
"""
Return
s
a pair condition used for joining and subquery pushdown. The
Return a pair condition used for joining and subquery pushdown. The
condition is something that responds to as_sql(compiler, connection)
method.
...
...
@@ -1765,6 +1844,14 @@ class ForeignObject(RelatedField):
class
ForeignKey
(
ForeignObject
):
"""
Provide a many-to-one relation by adding a column to the local model
to hold the remote value.
By default ForeignKey will target the pk of the remote model but this
behavior can be changed by using the ``to_field`` argument.
"""
# Field flags
many_to_many
=
False
many_to_one
=
True
...
...
@@ -1981,10 +2068,11 @@ class ForeignKey(ForeignObject):
class
OneToOneField
(
ForeignKey
):
"""
A OneToOneField is essentially the same as a ForeignKey, with the exception
that
always carries a "unique" constraint with it and the reverse relation
always returns the object pointed to (since there will only ever be one),
rather than returning a list.
that
it always carries a "unique" constraint with it and the reverse
relation always returns the object pointed to (since there will only ever
be one),
rather than returning a list.
"""
# Field flags
many_to_many
=
False
many_to_one
=
False
...
...
@@ -2018,7 +2106,7 @@ class OneToOneField(ForeignKey):
setattr
(
instance
,
self
.
attname
,
data
)
def
_check_unique
(
self
,
**
kwargs
):
#
override ForeignKey since check isn't applicable here
#
Override ForeignKey since check isn't applicable here.
return
[]
...
...
@@ -2078,6 +2166,15 @@ def create_many_to_many_intermediary_model(field, klass):
class
ManyToManyField
(
RelatedField
):
"""
Provide a many-to-many relation by using an intermediary model that
holds two ForeignKey fields pointed at the two sides of the relation.
Unless a ``through`` model was provided, ManyToManyField will use the
create_many_to_many_intermediary_model factory to automatically generate
the intermediary model.
"""
# Field flags
many_to_many
=
True
many_to_one
=
False
...
...
@@ -2296,10 +2393,10 @@ class ManyToManyField(RelatedField):
)
)
# Validate `through_fields`
# Validate `through_fields`
.
if
self
.
rel
.
through_fields
is
not
None
:
# Validate that we're given an iterable of at least two items
# and that none of them is "falsy"
# and that none of them is "falsy"
.
if
not
(
len
(
self
.
rel
.
through_fields
)
>=
2
and
self
.
rel
.
through_fields
[
0
]
and
self
.
rel
.
through_fields
[
1
]):
errors
.
append
(
...
...
@@ -2317,7 +2414,7 @@ class ManyToManyField(RelatedField):
# Validate the given through fields -- they should be actual
# fields on the through model, and also be foreign keys to the
# expected models
# expected models
.
else
:
assert
from_model
is
not
None
,
(
"ManyToManyField with intermediate "
...
...
@@ -2372,7 +2469,7 @@ class ManyToManyField(RelatedField):
def
deconstruct
(
self
):
name
,
path
,
args
,
kwargs
=
super
(
ManyToManyField
,
self
)
.
deconstruct
()
# Handle the simpler arguments
# Handle the simpler arguments
.
if
self
.
db_table
is
not
None
:
kwargs
[
'db_table'
]
=
self
.
db_table
if
self
.
rel
.
db_constraint
is
not
True
:
...
...
@@ -2395,7 +2492,7 @@ class ManyToManyField(RelatedField):
# of a swap.
swappable_setting
=
self
.
swappable_setting
if
swappable_setting
is
not
None
:
# If it's already a settings reference, error
# If it's already a settings reference, error
.
if
hasattr
(
kwargs
[
'to'
],
"setting_name"
):
if
kwargs
[
'to'
]
.
setting_name
!=
swappable_setting
:
raise
ValueError
(
...
...
@@ -2403,7 +2500,7 @@ class ManyToManyField(RelatedField):
"model that is swapped in place of more than one model "
"(
%
s and
%
s)"
%
(
kwargs
[
'to'
]
.
setting_name
,
swappable_setting
)
)
# Set it
from
django.db.migrations.writer
import
SettingsReference
kwargs
[
'to'
]
=
SettingsReference
(
kwargs
[
'to'
],
...
...
@@ -2439,7 +2536,10 @@ class ManyToManyField(RelatedField):
return
Field
.
get_choices
(
self
,
include_blank
=
False
)
def
_get_m2m_db_table
(
self
,
opts
):
"Function that can be curried to provide the m2m table name for this relation"
"""
Function that can be curried to provide the m2m table name for this
relation.
"""
if
self
.
rel
.
through
is
not
None
:
return
self
.
rel
.
through
.
_meta
.
db_table
elif
self
.
db_table
:
...
...
@@ -2449,7 +2549,10 @@ class ManyToManyField(RelatedField):
connection
.
ops
.
max_name_length
())
def
_get_m2m_attr
(
self
,
related
,
attr
):
"Function that can be curried to provide the source accessor or DB column name for the m2m table"
"""
Function that can be curried to provide the source accessor or DB
column name for the m2m table.
"""
cache_attr
=
'_m2m_
%
s_cache'
%
attr
if
hasattr
(
self
,
cache_attr
):
return
getattr
(
self
,
cache_attr
)
...
...
@@ -2464,7 +2567,10 @@ class ManyToManyField(RelatedField):
return
getattr
(
self
,
cache_attr
)
def
_get_m2m_reverse_attr
(
self
,
related
,
attr
):
"Function that can be curried to provide the related accessor or DB column name for the m2m table"
"""
Function that can be curried to provide the related accessor or DB
column name for the m2m table.
"""
cache_attr
=
'_m2m_reverse_
%
s_cache'
%
attr
if
hasattr
(
self
,
cache_attr
):
return
getattr
(
self
,
cache_attr
)
...
...
@@ -2474,7 +2580,6 @@ class ManyToManyField(RelatedField):
else
:
link_field_name
=
None
for
f
in
self
.
rel
.
through
.
_meta
.
fields
:
# NOTE f.rel.to != f.related_model
if
f
.
is_relation
and
f
.
rel
.
to
==
related
.
model
:
if
link_field_name
is
None
and
related
.
related_model
==
related
.
model
:
# If this is an m2m-intermediate to self,
...
...
@@ -2524,11 +2629,10 @@ class ManyToManyField(RelatedField):
if
not
self
.
rel
.
through
and
not
cls
.
_meta
.
abstract
and
not
cls
.
_meta
.
swapped
:
self
.
rel
.
through
=
create_many_to_many_intermediary_model
(
self
,
cls
)
# Add the descriptor for the m2m relation
# Add the descriptor for the m2m relation.
setattr
(
cls
,
self
.
name
,
ManyRelatedObjectsDescriptor
(
self
.
rel
,
reverse
=
False
))
# Set up the accessor for the m2m table name for the relation
# Set up the accessor for the m2m table name for the relation
.
self
.
m2m_db_table
=
curry
(
self
.
_get_m2m_db_table
,
cls
.
_meta
)
# Populate some necessary rel arguments so that cross-app relations
...
...
@@ -2544,7 +2648,7 @@ class ManyToManyField(RelatedField):
if
not
self
.
rel
.
is_hidden
()
and
not
related
.
related_model
.
_meta
.
swapped
:
setattr
(
cls
,
related
.
get_accessor_name
(),
ManyRelatedObjectsDescriptor
(
self
.
rel
,
reverse
=
True
))
# Set up the accessors for the column names on the m2m table
# Set up the accessors for the column names on the m2m table
.
self
.
m2m_column_name
=
curry
(
self
.
_get_m2m_attr
,
related
,
'column'
)
self
.
m2m_reverse_name
=
curry
(
self
.
_get_m2m_reverse_attr
,
related
,
'column'
)
...
...
@@ -2560,7 +2664,9 @@ class ManyToManyField(RelatedField):
pass
def
value_from_object
(
self
,
obj
):
"Returns the value of this field in the given model instance."
"""
Return the value of this field in the given model instance.
"""
return
getattr
(
obj
,
self
.
attname
)
.
all
()
def
save_form_data
(
self
,
instance
,
data
):
...
...
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