在Django中具有内部结构的字段

时间:2013-09-05 21:26:11

标签: django database-design django-models data-modeling database-schema

我想在Django中创建一个项目表。问题是每一个 项目具有不同的内部结构,我将不得不创建太多的表。

例如,如果item为CPU,我希望内部结构属性(列)如下:

type:processor
frequency:value
number of cores:value
socket:value

如果项目为smartphone,则内部结构为:

type:smartphone
os:value
displaysize:value
cpuID:value

在向数据库添加新项目时,该字段应首先询问用户要添加的类型(例如CPU),并根据此信息显示相应的表单 对于依赖于类型的内部结构属性。内部结构的某些字段将是必需的,但大部分将是可选的,并且有多个字段可以是多个(例如多个URL)。

实施此方法有哪些方法? Django中是否有一些帮助 这样的数据?各种方法的优点和缺点是什么? 到目前为止,我看到一个缺点。请注意,智能手机使用cpuID作为外键。是否可以保留参考文献?请注意,CPU可以引用它的制造商(仅举例说明各种项目可以对其他项目进行一些引用)。

1 个答案:

答案 0 :(得分:1)

一种方法是创建一个“主”表,其中包含所有公共属性和每种类型对象的单独表。这在Django中非常容易,模型定义看起来很“干净”,详见Multi-table inheritance

适合您情况的示例模型:

# 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.

请注意,每个“具体”项都包含两个数据库行:公用表和“具体”表。这两个表由“具体”表中的一对一字段连接(Django为您添加此字段,但如果需要,您可以重新定义它。)

从数据库中检索项目的示例方法:

# 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.

优点:

  1. 类定义看起来干净简单。
  2. 非常接近最佳数据库结构。
  3. 一个db查询可以检索各种类型的项目。
  4. 缺点:

    1. 检索具有完整数据的对象时连接过多。