Loading django/db/models/fields/related.py +3 −5 Original line number Diff line number Diff line Loading @@ -960,6 +960,7 @@ class ManyToManyRel(object): class ForeignObject(RelatedField): requires_unique_target = True generate_reverse_relation = True related_accessor_class = ForeignRelatedObjectsDescriptor def __init__(self, to, from_fields, to_fields, **kwargs): self.from_fields = from_fields Loading Loading @@ -1160,7 +1161,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.rel.is_hidden() and not related.model._meta.swapped: setattr(cls, related.get_accessor_name(), ForeignRelatedObjectsDescriptor(related)) setattr(cls, related.get_accessor_name(), self.related_accessor_class(related)) if self.rel.limit_choices_to: cls._meta.related_fkey_lookups.append(self.rel.limit_choices_to) Loading Loading @@ -1334,6 +1335,7 @@ class OneToOneField(ForeignKey): always returns the object pointed to (since there will only ever be one), rather than returning a list. """ related_accessor_class = SingleRelatedObjectDescriptor description = _("One-to-one relationship") def __init__(self, to, to_field=None, **kwargs): Loading @@ -1346,10 +1348,6 @@ class OneToOneField(ForeignKey): del kwargs['unique'] return name, path, args, kwargs def contribute_to_related_class(self, cls, related): setattr(cls, related.get_accessor_name(), SingleRelatedObjectDescriptor(related)) def formfield(self, **kwargs): if self.rel.parent_link: return None Loading docs/releases/1.7.txt +5 −0 Original line number Diff line number Diff line Loading @@ -289,6 +289,11 @@ Models * Explicit :class:`~django.db.models.OneToOneField` for :ref:`multi-table-inheritance` are now discovered in abstract classes. * Is it now possible to avoid creating a backward relation for :class:`~django.db.models.OneToOneField` by setting its :attr:`~django.db.models.ForeignKey.related_name` to `'+'` or ending it with `'+'`. Signals ^^^^^^^ Loading tests/one_to_one_regress/models.py +13 −2 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ class Place(models.Model): def __str__(self): return "%s the place" % self.name @python_2_unicode_compatible class Restaurant(models.Model): place = models.OneToOneField(Place) Loading @@ -21,6 +22,7 @@ class Restaurant(models.Model): def __str__(self): return "%s the restaurant" % self.place.name @python_2_unicode_compatible class Bar(models.Model): place = models.OneToOneField(Place) Loading @@ -29,10 +31,12 @@ class Bar(models.Model): def __str__(self): return "%s the bar" % self.place.name class UndergroundBar(models.Model): place = models.OneToOneField(Place, null=True) serves_cocktails = models.BooleanField(default=True) @python_2_unicode_compatible class Favorites(models.Model): name = models.CharField(max_length=50) Loading @@ -41,11 +45,18 @@ class Favorites(models.Model): def __str__(self): return "Favorites for %s" % self.name class Target(models.Model): pass class Pointer(models.Model): other = models.OneToOneField(Target, primary_key=True) class Pointer2(models.Model): other = models.OneToOneField(Target) other = models.OneToOneField(Target, related_name='second_pointer') class HiddenPointer(models.Model): target = models.OneToOneField(Target, related_name='hidden+') tests/one_to_one_regress/tests.py +13 −3 Original line number Diff line number Diff line Loading @@ -2,7 +2,8 @@ from __future__ import unicode_literals from django.test import TestCase from .models import Place, Restaurant, Bar, Favorites, Target, UndergroundBar from .models import (Bar, Favorites, HiddenPointer, Place, Restaurant, Target, UndergroundBar) class OneToOneRegressionTests(TestCase): Loading Loading @@ -125,11 +126,11 @@ class OneToOneRegressionTests(TestCase): [] ) self.assertQuerysetEqual( Target.objects.filter(pointer2=None), Target.objects.filter(second_pointer=None), ['<Target: Target object>'] ) self.assertQuerysetEqual( Target.objects.exclude(pointer2=None), Target.objects.exclude(second_pointer=None), [] ) Loading Loading @@ -250,3 +251,12 @@ class OneToOneRegressionTests(TestCase): self.p1.delete() self.assertTrue(UndergroundBar.objects.filter(pk=u.pk).exists()) self.assertIsNone(UndergroundBar.objects.get(pk=u.pk).place) def test_hidden_accessor(self): """ When a '+' ending related name is specified no reverse accessor should be added to the related model. """ self.assertFalse( hasattr(Target, HiddenPointer._meta.get_field('target').related.get_accessor_name()) ) Loading
django/db/models/fields/related.py +3 −5 Original line number Diff line number Diff line Loading @@ -960,6 +960,7 @@ class ManyToManyRel(object): class ForeignObject(RelatedField): requires_unique_target = True generate_reverse_relation = True related_accessor_class = ForeignRelatedObjectsDescriptor def __init__(self, to, from_fields, to_fields, **kwargs): self.from_fields = from_fields Loading Loading @@ -1160,7 +1161,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.rel.is_hidden() and not related.model._meta.swapped: setattr(cls, related.get_accessor_name(), ForeignRelatedObjectsDescriptor(related)) setattr(cls, related.get_accessor_name(), self.related_accessor_class(related)) if self.rel.limit_choices_to: cls._meta.related_fkey_lookups.append(self.rel.limit_choices_to) Loading Loading @@ -1334,6 +1335,7 @@ class OneToOneField(ForeignKey): always returns the object pointed to (since there will only ever be one), rather than returning a list. """ related_accessor_class = SingleRelatedObjectDescriptor description = _("One-to-one relationship") def __init__(self, to, to_field=None, **kwargs): Loading @@ -1346,10 +1348,6 @@ class OneToOneField(ForeignKey): del kwargs['unique'] return name, path, args, kwargs def contribute_to_related_class(self, cls, related): setattr(cls, related.get_accessor_name(), SingleRelatedObjectDescriptor(related)) def formfield(self, **kwargs): if self.rel.parent_link: return None Loading
docs/releases/1.7.txt +5 −0 Original line number Diff line number Diff line Loading @@ -289,6 +289,11 @@ Models * Explicit :class:`~django.db.models.OneToOneField` for :ref:`multi-table-inheritance` are now discovered in abstract classes. * Is it now possible to avoid creating a backward relation for :class:`~django.db.models.OneToOneField` by setting its :attr:`~django.db.models.ForeignKey.related_name` to `'+'` or ending it with `'+'`. Signals ^^^^^^^ Loading
tests/one_to_one_regress/models.py +13 −2 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ class Place(models.Model): def __str__(self): return "%s the place" % self.name @python_2_unicode_compatible class Restaurant(models.Model): place = models.OneToOneField(Place) Loading @@ -21,6 +22,7 @@ class Restaurant(models.Model): def __str__(self): return "%s the restaurant" % self.place.name @python_2_unicode_compatible class Bar(models.Model): place = models.OneToOneField(Place) Loading @@ -29,10 +31,12 @@ class Bar(models.Model): def __str__(self): return "%s the bar" % self.place.name class UndergroundBar(models.Model): place = models.OneToOneField(Place, null=True) serves_cocktails = models.BooleanField(default=True) @python_2_unicode_compatible class Favorites(models.Model): name = models.CharField(max_length=50) Loading @@ -41,11 +45,18 @@ class Favorites(models.Model): def __str__(self): return "Favorites for %s" % self.name class Target(models.Model): pass class Pointer(models.Model): other = models.OneToOneField(Target, primary_key=True) class Pointer2(models.Model): other = models.OneToOneField(Target) other = models.OneToOneField(Target, related_name='second_pointer') class HiddenPointer(models.Model): target = models.OneToOneField(Target, related_name='hidden+')
tests/one_to_one_regress/tests.py +13 −3 Original line number Diff line number Diff line Loading @@ -2,7 +2,8 @@ from __future__ import unicode_literals from django.test import TestCase from .models import Place, Restaurant, Bar, Favorites, Target, UndergroundBar from .models import (Bar, Favorites, HiddenPointer, Place, Restaurant, Target, UndergroundBar) class OneToOneRegressionTests(TestCase): Loading Loading @@ -125,11 +126,11 @@ class OneToOneRegressionTests(TestCase): [] ) self.assertQuerysetEqual( Target.objects.filter(pointer2=None), Target.objects.filter(second_pointer=None), ['<Target: Target object>'] ) self.assertQuerysetEqual( Target.objects.exclude(pointer2=None), Target.objects.exclude(second_pointer=None), [] ) Loading Loading @@ -250,3 +251,12 @@ class OneToOneRegressionTests(TestCase): self.p1.delete() self.assertTrue(UndergroundBar.objects.filter(pk=u.pk).exists()) self.assertIsNone(UndergroundBar.objects.get(pk=u.pk).place) def test_hidden_accessor(self): """ When a '+' ending related name is specified no reverse accessor should be added to the related model. """ self.assertFalse( hasattr(Target, HiddenPointer._meta.get_field('target').related.get_accessor_name()) )