Reputation: 1159
I am new to Django framework and in my project I have a model called Layer.
class Layer(models.Model):
name = models.CharField(max_length=255)
I would like layer to have a relationship with an abstract model called "Geometry", more specifically, one layer should have one or no Geometry and one Geometry should be owned by one layer.
The problem is that I have for types of Geometries and they all have different properties, so I decided to create multiple geometries:
class Circle(models.Model):
radius = models.CharField(max_length=255)
class Rectangle(models.Model):
height = models.CharField(max_length=255)
width = models.CharField(max_length=255)
I would like to have a data structure where both models are of the same type (Geometry). I would like to call layer.geometry and be able to get either a circle or a rectangle, or a cross and so on. Is that possible? And how is the database shape going to be like? Is Django going to create two different tables or one table with merged properties?
Thanks in advance
Upvotes: 2
Views: 524
Reputation: 77
Although you can link Cirle
and Rectangle
models with ForeignKey
or OneToOneField
, your have an option to create an AbstractModel
for Geometry
model.
class Geometry(models.Model):
id = models.IntegerField()
class Meta:
abstract = True
class Circle(Geometry):
radius = models.CharField(max_length=255)
class Rectangle(Geometry):
height = models.CharField(max_length=255)
width = models.CharField(max_length=255)
As such, both Circle
and Rectangle
models will have id field from Geometry
model, but will only have 2 tables in your database. However, you wont be able to query in Geometry
model.
If you need to query explicitly for Geometry
model, go for ForeignKey
or OneToOneField
option. If not, abstract
model is a cleaner approach in my opinion.
From Django Docs: Often, you will just want to use the parent class to hold information that you don’t want to have to type out for each child model. This class isn’t going to ever be used in isolation, so Abstract base classes are what you’re after.
Upvotes: 0
Reputation: 476729
Django supports inheritance, although it is not very common. You can thus create a model Geometry
, and let Circle
and Rectangle
inherit from that:
class Geometry(models.Model):
pass
class Circle(Geometry):
radius = models.CharField(max_length=255)
class Rectangle(Geometry):
height = models.CharField(max_length=255)
width = models.CharField(max_length=255)
We can furthermore make a ForeignKey
(or another relation) to this Geometry
class with:
class Layer(models.Model):
name = models.CharField(max_length=255)
geometry = models.ForeignKey(Geometry, on_delete=models.CASCADE)
Django will make migrations that, for an SQL database create tables for Geometry
, Circle
and Rectangle
. The Circle
and Rectangle
models will have an implicit OneToOneRelation
to the table for the Geometry
named geometry_ptr_id
, that thus refers to the parent.
For more information, see the section on Multi-table inheritance in the documentation.
Upvotes: 4