How can I make sure that a parent object has only one child/type?
class Property(...):
class Meta:
abstract = False
class Flat(Property):
pass
class House(Property):
pass
class Land(Property):
pass
I want every property object to have none or at most one child. It can be either flat
, house
or land
(or null
).
Is it possible to create a DB constraint for this?
My idea was to create a constraint that checks:
class Meta:
constraints = [
models.CheckConstraint(check=Q(Q(flat__isnull=True) & Q(house__isnull=True))
|
Q(Q(flat__isnull=True) & Q(land__isnull=True))
|
Q(Q(house__isnull=True) & Q(land__isnull=True)),
name="constraint")]
But apparently, there are no such fields on a DB level (you can get flat
by property.flat
getter in Django but not in DB)
properties.Property: (models.E012) 'constraints' refers to the nonexistent field 'flat'.
But apparently, there are no such fields on a DB level (you can get flat by
property.flat
getter in Django but not in DB)
That is correct: Django adds a property to the Property
model to lazily load the related Flat
object and will make a query for that, but there is no database field named flat
: this is just a query in reverse where Django basically queries with:
SELECT * FROM app_name_flat WHERE property_ptr=pk
with pk
the primary key of the property
object. It this makes a query.
A CHECK
constraint [w3-schools] spans only over a row: it can not look on other rows nor can it look at other tables. It thus can not restrict other tables, and therefore is limited. It can for example prevent one column to have a certain value based on a value for another column in the same row (record), but that is how far a CHECK
constraint normally looks.