Возможно ли в Django иметь поле OneToOneField, которое имеет значение null=True только в одном направлении?
Можно ли в Django создать OneToOneField
, который будет null=True
только в одном направлении?
Ex:
class Building(models.Model):
...
class Roof(models.Model):
building = models.OneToOneField(...)
...
Технически здание не обязательно должно иметь крышу. Множество недостроенных зданий не имеют ее. Но вы не можете иметь крышу без здания.
Кроме того, у здания может быть только одна крыша, а крыша может быть только на одном здании, поэтому OneToOneField
.
Ваши модели в установленном виде уже достигают этого.
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
Остается Building b1
без Roof
, и Building b2
с Roof r2
.
Помните, что OneToOneField
не является "симметричным", в том смысле, что имеет значение, в какую из двух моделей вы поместите поле. С вашими моделями, как они определены, вы в конечном итоге будете иметь базовую таблицу базы данных Building
без упоминания Roof
, и таблицу Roof
, которая содержит столбец с foreign key
(с ограничением unique
) обратно к Building
. Вот почему создание Building
не требует указания Roof
, а создание Roof
требует указания связанных Building
.