Django:结构Django模型允许任意Fieldtypes

时间:2009-08-07 05:42:23

标签: django django-models

我想在Django中创建一个用户配置文件应用程序(我知道有一些存在,谢谢),我想知道如何构建模型以允许每个子部分中的任意组合字段。

例如,“教育”部分可能有一个名为“编程体验”的子部分,“个人信息”部分可能有一个名为“收藏夹”的子部分。

根据典型的侧栏导航设置进行思考,每个部分都是标题,每个子部分都是指向可以操纵信息的表单的链接。

Education
- Schooling
- Programming Experience

Personal Info
- Location
- Favourites
- Look a-likes

我想做的是能够在任意的基础上向子部分添加项目。无论网站的感受如何。

也许一个网站会从用户参加的学校的照片中受益,而另一个网站可能只需要描述。

我想使用管理界面将这些字段类型添加到子部分。因此,添加项目将显示选择的信息类型(图像,视频,文本等)以及应用于哪个子部分。

我想知道你将如何实现这一目标;更重要的是,通过尽可能少的箍跳。

感谢。

编辑:

为了澄清这个问题,我将提供一个示例models.py文件。这只是一个快速的moch-up来更准确地证明问题。我有两个解决方案,我认为解决方案二比解决方案一更好;但是我也想在这里SO社区的想法,以及他们是否有其他任何解决方案。

**models.py**

class Section(models.Model):
    """
    The root of categorization. Acts much like a header
    """
    name = models.CharField(max_length=30)
    description = models.CharField(max_length=255)

class SubSection(models.Model):
    """
    The contents of each section. Contains many items of varying types as needed
    by the site developer.
    """
    name = models.CharField(max_length=30)
    description = models.CharField(max_length=255)
    section = models.ForeignKey(Section)

class Item(models.Model):
    """
    I would like this to store the information here and have a foreign key to the
    'SubSection' table. The problem is that there are a lot of different information
    types that can be stored and I'd need a row for each type. Thus for each
    entry most of the columns will be blank.

    I'm thinking that it may be better to use this table as a pointer to another
    table that actually contains the information. This will result in a lot of
    tables but will eliminate waste.
    """

    name = models.CharField(max_length=30)
    description = models.CharField(max_length=255)
    sub_section = models.ForeignKey(SubSection)

    ### Solution One
    # Storing the info here results in a lot of wasted space and may not be all
    # that flexible
    image = models.ImageField()
    text = models.CharField(max_length=255)
    numeric = models.IntegerField()
    time = models.TimeField()
    # etc ...

    ### Solution Two
    # Storing the field info results in more tables but allows for a better match
    # of information and field type.
    field_type = models.CharField(max_length=255)
    field_properties = models.CommaSeparatedIntegerField(max_length=None)


### Solution Two Tables
# Solution two would require a table for each field type supported here, which
# is quite a few different types.

class ImageStorage(models.Model):
    item = models.ForeignKey(Item)
    information = models.ImageField()

class IntegerStorage(models.Model):
    item = models.ForeignKey(Item)
    information = models.IntegerField()

### etc ...

请记住,它是针对用户个人资料的。因此,减重网站可能希望用户在配置文件中的当前权重(数字信息),而旅行网站可能想要访问的地点列表(文本信息,甚至可以使用我想的IPAddressField)。我只是不知道会弹出什么,所以我试图让它尽可能通用。

1 个答案:

答案 0 :(得分:0)

如果我理解你,最简单的方法就是多对一的关系。我不确定您是希望在每个用户还是每个站点上进行这些操作,因此我假设您希望每个站点自定义它(切换很容易)。

创建一个如下所示的表:

class Section(models.Model):
    section = models.CharField()
    sub-section = model.CharField()
    site = models.ForeignKey(Site)

对于属于同一部分的多个子部分,只需为它们指定相同的主要部分名称,以便您可以使用该名称在DB中查询附带的子部分。

另一种方法是使用两个表来完成同样的事情,但考虑到应用程序,我认为这可能更合适。