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