Commit f95122e5 authored by Anssi Kääriäinen's avatar Anssi Kääriäinen Committed by Tim Graham
Browse files

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.
parent 78d43a5e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -316,7 +316,7 @@ def label_for_field(name, model, model_admin=None, return_attr=False):
            label = field.verbose_name
        except AttributeError:
            # field is likely a ForeignObjectRel
            label = field.opts.verbose_name
            label = field.related_model._meta.verbose_name
    except FieldDoesNotExist:
        if name == "__unicode__":
            label = force_text(model._meta.verbose_name)
+10 −14
Original line number Diff line number Diff line
@@ -500,7 +500,7 @@ class SingleRelatedObjectDescriptor(object):
                    value,
                    instance._meta.object_name,
                    self.related.get_accessor_name(),
                    self.related.opts.object_name,
                    self.related.related_model._meta.object_name,
                )
            )
        elif value is not None:
@@ -1305,14 +1305,6 @@ class ForeignObjectRel(object):
    def model(self):
        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
    def hidden(self):
        return self.is_hidden()
@@ -1345,7 +1337,11 @@ class ForeignObjectRel(object):
        return self.field.one_to_one

    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,
                    limit_to_currently_related=False):
@@ -1396,7 +1392,7 @@ class ForeignObjectRel(object):
        # but this can be overridden with the "related_name" option.
        # Due to backwards compatibility ModelForms need to be able to provide
        # 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
        if self.multiple:
            # 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:
            return self.related_name
        if opts.default_related_name:
            return self.opts.default_related_name % {
                'model_name': self.opts.model_name.lower(),
                'app_label': self.opts.app_label.lower(),
            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 '')

+3 −0
Original line number Diff line number Diff line
@@ -43,6 +43,9 @@ class PickleabilityTestCase(TestCase):
    def test_membermethod_as_default(self):
        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):
        # Ticket #17776
        original = Event.DoesNotExist("Doesn't exist")