1đź‘Ť
âś…
One approach would be to create a “main” table with all the common properties and separate tables for each type of object. This is very easy to do in Django and model definitions look “clean”, see Multi-table inheritance for details.
Example models for your situation:
# Hold common fields/properties
class Item(models.Model):
type = ...
price = ...
weight = ...
width = ...
height = ...
...
# Below are example classes which will inherit all properties from Item
class CPU(Item):
frequency = ...
core_count = ...
socket = ...
class Smartphone(Item):
os = ...
display_size = ...
cpu = models.ForeignKey(CPU, ...) # Example linking between items.
Note that each “concrete” item consists of two database rows: the common table and in the “concrete” table. The two tables are joined by a one to one field in the “concrete” table (Django adds this field for you, but you can redefine it, if you want).
Example methods of retrieving items from database:
# Get all "base" items without touching type tables
Item.objects.all()
# Get all items along with their child properties. This is rather ugly and expensive.
Item.objects.select_related('cpu', 'smarthphone', ...).all()
# Gets smartphones, uses a join to retrieve data from two tables.
# I don't remeber if the `select_related` is required here.
Smartphone.objects.select_related('item').all()
# When type of the item is only know at runtime, you can query like this (requires additional table column for storing type):
Item.objects.filter(type='smartphone')
# Or alternatively finding out which type class you want.
Advantages:
- Class definitions look clean and simple.
- Very close to optimal database structure.
- One db query can retrieve items of various types.
Disadvantages:
- Excessive joins when retrieving objects with full data.
👤HankMoody
Source:stackexchange.com