Возможно ли в 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.

Вернуться на верх