Commit 3918eeb9 authored by Bouke Haarsma's avatar Bouke Haarsma Committed by Tim Graham
Browse files

Fixed #7551 -- Made GFK allow None init argument.

Thanks SamBull for the report.
parent 763ac8b6
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -59,8 +59,12 @@ class GenericForeignKey(six.with_metaclass(RenameGenericForeignKeyMethods)):
        """
        if self.name in kwargs:
            value = kwargs.pop(self.name)
            if value is not None:
                kwargs[self.ct_field] = self.get_content_type(obj=value)
                kwargs[self.fk_field] = value._get_pk_val()
            else:
                kwargs[self.ct_field] = None
                kwargs[self.fk_field] = None

    def get_content_type(self, obj=None, id=None, using=None):
        if obj is not None:
+7 −0
Original line number Diff line number Diff line
@@ -137,3 +137,10 @@ class ConcreteRelatedModel(models.Model):
class ProxyRelatedModel(ConcreteRelatedModel):
    class Meta:
        proxy = True


# To test fix for #7551
class AllowsNullGFK(models.Model):
    content_type = models.ForeignKey(ContentType, null=True)
    object_id = models.PositiveIntegerField(null=True)
    content_object = generic.GenericForeignKey()
+16 −1
Original line number Diff line number Diff line
@@ -4,11 +4,12 @@ from django import forms
from django.contrib.contenttypes.generic import generic_inlineformset_factory
from django.contrib.contenttypes.models import ContentType
from django.test import TestCase
from django.utils import six

from .models import (TaggedItem, ValuableTaggedItem, Comparison, Animal,
                     Vegetable, Mineral, Gecko, Rock, ManualPK,
                     ForProxyModelModel, ForConcreteModelModel,
                     ProxyRelatedModel, ConcreteRelatedModel)
                     ProxyRelatedModel, ConcreteRelatedModel, AllowsNullGFK)


class GenericRelationsTests(TestCase):
@@ -440,3 +441,17 @@ class ProxyRelatedModelTest(TestCase):
        newrel.bases = [base]
        newrel = ConcreteRelatedModel.objects.get(pk=newrel.pk)
        self.assertEqual(base, newrel.bases.get())


class TestInitWithNoneArgument(TestCase):
    def test_none_not_allowed(self):
        # TaggedItem requires a content_type, initializing with None should
        # raise a ValueError.
        with six.assertRaisesRegex(self, ValueError,
          'Cannot assign None: "TaggedItem.content_type" does not allow null values'):
            TaggedItem(content_object=None)

    def test_none_allowed(self):
        # AllowsNullGFK doesn't require a content_type, so None argument should
        # also be allowed.
        AllowsNullGFK(content_object=None)