﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
7778	Model subclasses cannot be deleted if a nullable foreign key relates to a model that relates back	James Murty		"We use model subclasses in our application and we have come across a situation where Django gets confused when it tries to delete a model object and its related items. Our model contains a class that refers to a base/subclass model with a foreign key, and the base/subclass model in refers back to this class in turn.

The example below should make this clearer. Let's say we are interested in celebrities, which are categorised into subclasses including the TV Chef celebrity subclass. Celebrities can have multiple fans, but a celebrity can have only one ""greatest"" fan.

{{{
class Celebrity(models.Model):
    name = models.CharField(""Name"", max_length=20)
    greatest_fan = models.ForeignKey(""Fan"", null=True, unique=True)

class TvChef(Celebrity):
    pass
    

class Fan(models.Model):
    fan_of = models.ForeignKey(Celebrity)    
}}}

With these model relationships, Django will be unable to delete the !TvChef subclass if it has multiple related Fans. If you run the test program below, it will try to nullify a non-existent column in the !TvChef database table.

{{{
from subclass_deletion.models import *

c1 = Celebrity.objects.create(name=""Madonna"")
c2 = Celebrity.objects.create(name=""The Queen"")
c3 = TvChef.objects.create(name=""Huey"")

f1 = Fan.objects.create(fan_of=c3)
f2 = Fan.objects.create(fan_of=c3)

c3.greatest_fan = f1
c3.save()

# You cannot delete the TvChef subclass, it fails with the error:
#   OperationalError: no such column: greatest_fan_id
# This error occurs when it tries to run the SQL (sqlite3):
#   UPDATE ""subclass_deletion_tvchef"" SET ""greatest_fan_id"" = NULL WHERE ""celebrity_ptr_id"" IN (3)
c3.delete()
}}}

The attached patch performs a sanity-check before Django attempts to clear related fields, and will avoid doing so if it cannot find the expected column name in the class that is the ""to"" destination.
"		closed	Core (Other)	dev		fixed	foreign key	bthomas@… simon@… Darren.Foreman@… viktor@…	Accepted	1	0	0	1	0	0
