Django database design - Null Forign Keys
I have a Django model with a Person model:
class Person(models.Model):
# Personal details
first_name = models.CharField(max_length=50)
middle_name = models.CharField(max_length=50, blank=True, null=True)
last_name = models.CharField(max_length=50)
gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
date_of_birth = models.DateField()
# Address
street开发者_JAVA技巧_address = models.CharField(max_length=50)
suburb = models.CharField(max_length=30)
postcode = models.CharField(max_length=4)
state = models.CharField(max_length=3, choices=STATE_CHOICES)
#Contact Details
email = models.EmailField()
# Family
spouse = models.ForeignKey('self', null=True, blank=True)
children = models.ManyToManyField('self', null=True, blank=True)
home_church = models.ForeignKey('Church', null=True, blank=True)
The "middle_name" field is nullable, I don't think there's any way to avoid that, is there?
However, I also have a nullable ForeignKey for Spouse, a recursive ManyToManyField for their children, and a nullable ForeignKey for church (if relevant).
My question - firstly, what is the current consensus on nullable foreign keys? Should I be allowing it here, or should I be creating some kind of "nobody", or "unassigned" model to represent not having a spouse/home church?
Or is there some other way that I can rework this design in Django to accommodate for this?
And if I do go ahead with null FK's, are there any caveats in Django I need to be aware of? (left join?)
Cheers, Victor
Null is perfectly fine. In python code None
will represent Null
.
One important thing you should know is that if you delete church, django performs cascading and your Persons from that church will be deleted too. So before deleting church you need to set Null on church field for every person in that church.
Django 1.3 introduces on_delete argument which makes this a lot simper.
Nullable foreign keys as implemented by most DBMSs don't make much logical sense. There are also some inconsistencies between the ways that different DBMSs handle them. As a result, nullable foreign keys are very likely to lead to incorrect results. They are easily avoided simply by moving the attribute(s) in question to a new table and only populating that table when you have a value to populate it with.
When the foreign key is marked null = True, Django will process the JOINs with LEFT OUTER JOIN, at least with an Oracle database AFAIK, so no problem there.
精彩评论