Is it possible to create a OneToOneField
in Django that is only null=True
in one direction?
Ex:
class Building(models.Model):
...
class Roof(models.Model):
building = models.OneToOneField(...)
...
A building doesn't technically need to have a roof. Plenty of unfinished buildings don't have them. But you can't have a roof without a building.
Also, a building can only have one roof, and a roof can only be on one building, hence OneToOneField
.
CodePudding user response:
Your models as setup already accomplishes that.
b1 = models.Building.objects.create() # no error
b2 = models.Building.objects.create() # no error
r1 = models.Roof.objects.create() # violates null constraint
psycopg2.errors.NotNullViolation: null value in column "building_id" of
relation "users_roof" violates not-null constraint
r2 = models.Roof.objects.create(building=b2) # no error
You're left with Building b1
with no Roof
, and Building b2
with Roof r2
.
Keep in mind that OneToOneField
is not "symmetric", in the sense that it matters which of the two models you put the field in. With your models as defined, you will basically end up with an underlying Building
database table with no mention of Roof
, and a Roof
table that contains a column with a foreign key
(with a unique
constraint) back to Building
. That is why creating a Building
does not require specifying a Roof
, but creating a Roof
requires specifying the associated Building
.