mirror of https://github.com/django/django.git
Fixed #24381 -- removed ForeignObjectRel opts and to_opts
These cached properies were causing problems with pickling, and in addition they were confusingly defined: field.rel.model._meta was not the same as field.rel.opts. Instead users should use field.rel.related_model._meta inplace of field.rel.opts, and field.rel.to._meta in place of field.rel.to_opts.
This commit is contained in:
parent
78d43a5e10
commit
f95122e541
|
@ -316,7 +316,7 @@ def label_for_field(name, model, model_admin=None, return_attr=False):
|
||||||
label = field.verbose_name
|
label = field.verbose_name
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# field is likely a ForeignObjectRel
|
# field is likely a ForeignObjectRel
|
||||||
label = field.opts.verbose_name
|
label = field.related_model._meta.verbose_name
|
||||||
except FieldDoesNotExist:
|
except FieldDoesNotExist:
|
||||||
if name == "__unicode__":
|
if name == "__unicode__":
|
||||||
label = force_text(model._meta.verbose_name)
|
label = force_text(model._meta.verbose_name)
|
||||||
|
|
|
@ -500,7 +500,7 @@ class SingleRelatedObjectDescriptor(object):
|
||||||
value,
|
value,
|
||||||
instance._meta.object_name,
|
instance._meta.object_name,
|
||||||
self.related.get_accessor_name(),
|
self.related.get_accessor_name(),
|
||||||
self.related.opts.object_name,
|
self.related.related_model._meta.object_name,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
elif value is not None:
|
elif value is not None:
|
||||||
|
@ -1305,14 +1305,6 @@ class ForeignObjectRel(object):
|
||||||
def model(self):
|
def model(self):
|
||||||
return self.to
|
return self.to
|
||||||
|
|
||||||
@cached_property
|
|
||||||
def opts(self):
|
|
||||||
return self.related_model._meta
|
|
||||||
|
|
||||||
@cached_property
|
|
||||||
def to_opts(self):
|
|
||||||
return self.to._meta
|
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def hidden(self):
|
def hidden(self):
|
||||||
return self.is_hidden()
|
return self.is_hidden()
|
||||||
|
@ -1345,7 +1337,11 @@ class ForeignObjectRel(object):
|
||||||
return self.field.one_to_one
|
return self.field.one_to_one
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<%s: %s.%s>' % (type(self).__name__, self.opts.app_label, self.opts.model_name)
|
return '<%s: %s.%s>' % (
|
||||||
|
type(self).__name__,
|
||||||
|
self.related_model._meta.app_label,
|
||||||
|
self.related_model._meta.model_name,
|
||||||
|
)
|
||||||
|
|
||||||
def get_choices(self, include_blank=True, blank_choice=BLANK_CHOICE_DASH,
|
def get_choices(self, include_blank=True, blank_choice=BLANK_CHOICE_DASH,
|
||||||
limit_to_currently_related=False):
|
limit_to_currently_related=False):
|
||||||
|
@ -1396,7 +1392,7 @@ class ForeignObjectRel(object):
|
||||||
# but this can be overridden with the "related_name" option.
|
# but this can be overridden with the "related_name" option.
|
||||||
# Due to backwards compatibility ModelForms need to be able to provide
|
# Due to backwards compatibility ModelForms need to be able to provide
|
||||||
# an alternate model. See BaseInlineFormSet.get_default_prefix().
|
# an alternate model. See BaseInlineFormSet.get_default_prefix().
|
||||||
opts = model._meta if model else self.opts
|
opts = model._meta if model else self.related_model._meta
|
||||||
model = model or self.related_model
|
model = model or self.related_model
|
||||||
if self.multiple:
|
if self.multiple:
|
||||||
# If this is a symmetrical m2m relation on self, there is no reverse accessor.
|
# If this is a symmetrical m2m relation on self, there is no reverse accessor.
|
||||||
|
@ -1405,9 +1401,9 @@ class ForeignObjectRel(object):
|
||||||
if self.related_name:
|
if self.related_name:
|
||||||
return self.related_name
|
return self.related_name
|
||||||
if opts.default_related_name:
|
if opts.default_related_name:
|
||||||
return self.opts.default_related_name % {
|
return opts.default_related_name % {
|
||||||
'model_name': self.opts.model_name.lower(),
|
'model_name': opts.model_name.lower(),
|
||||||
'app_label': self.opts.app_label.lower(),
|
'app_label': opts.app_label.lower(),
|
||||||
}
|
}
|
||||||
return opts.model_name + ('_set' if self.multiple else '')
|
return opts.model_name + ('_set' if self.multiple else '')
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,9 @@ class PickleabilityTestCase(TestCase):
|
||||||
def test_membermethod_as_default(self):
|
def test_membermethod_as_default(self):
|
||||||
self.assert_pickles(Happening.objects.filter(number4=1))
|
self.assert_pickles(Happening.objects.filter(number4=1))
|
||||||
|
|
||||||
|
def test_filter_reverse_fk(self):
|
||||||
|
self.assert_pickles(Group.objects.filter(event=1))
|
||||||
|
|
||||||
def test_doesnotexist_exception(self):
|
def test_doesnotexist_exception(self):
|
||||||
# Ticket #17776
|
# Ticket #17776
|
||||||
original = Event.DoesNotExist("Doesn't exist")
|
original = Event.DoesNotExist("Doesn't exist")
|
||||||
|
|
Loading…
Reference in New Issue