【问题标题】:django model designing for 3 linked lists3个链表的django模型设计
【发布时间】:2016-05-05 13:33:05
【问题描述】:

我打算在 django 中设计一个基于 Web 的数据库。在我的页面中,所有议会问题的工作都是自动化的。这里是一个表格示例:

在我的输入表单中,会有很多字段,包括 Department 和 Division 字段。根据上表,当我选择第 1 组时,所有三个部委 A、B、C 将作为下拉列表出现在部委字段下。同样,当我从下拉列表中选择部门 A 时,所有三个部门 X、Y、Z 都将位于部门下拉列表的标签下。请注意,您可能会注意到所有的事工都没有分裂。所以当一个部门没有部门时,部门字段将被隐藏。

为了实现这一点,我正在考虑以下模型:

from django.db import models

class Group(models.Model):
    name = models.CharField(max_length=8, unique=True)
    slug = models.SlugField(max_length=8, unique=True,
        help_text='A label for URL config.')

class Ministry(models.Model):
    name = models.CharField(max_length=90, unique=True)
    slug = models.SlugField(max_length=90, unique=True,
        help_text='A label for URL config.')
    group = models.ForeignKey(Group)

class Division(models.Model):
    name = models.CharField(max_length=90, unique=True)
    slug = models.SlugField(max_length=90, unique=True,
        help_text='A label for URL config.')
    ministry = models.ForeignKey(Ministry)

我的方法是正确的吗?欢迎提出任何改进建议。

编辑:

django-mptt 模型:

from django.db import models
from mptt.models import MPTTModel, TreeForeignKey
from django.core.urlresolvers import reverse


class Genre(MPTTModel):
    name = models.CharField(max_length=50, unique=True)
    parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True)

    def get_absolute_url(self):
        return reverse('genre_detail', kwargs={'pk': self.pk,})

    class MPTTMeta:
        order_insertion_by = ['name']

    def __str__(self):
        return self.name

django-mptt 输出:

Group-1
    Ministry A
        Division A
        Division B
        Division C
    Ministry B
    Ministry C
        Division D
        Division E
    Ministry D
Group-2
    Ministry E
        Division G
        Division Z
    Ministry F
        Division I
        Division J

但是如何使这棵树成为我的示例表?

【问题讨论】:

  • 我的看法是,如果不会超过这3个级别就可以了。如果这个层次结构可以增长,我会使用嵌套模型之类的东西。 en.wikipedia.org/wiki/Nested_set_model
  • @Milos Miletic,将有 10 个级别,每个级别将分配给特定日期。这将在议会会议期间、近 20 个工作日或工作日期间循环持续。我浏览了您的链接页面,但无法理解它是如何在 django 中实现的。能给点提示吗?

标签: django python-3.x django-models django-forms


【解决方案1】:

我会使用另外一种模型,例如

class MyRecord(models.Model): #please pick a better name
    group = models.ForeignKey('Group')
    ministry = models.ForeignKey('Ministry')
    division = models.ForeignKey('Division', null=True)

现在每一行都将包含对数据的 3 引用...

您的表格将如下所示:

ID |集团 |事工 |师|

1 |一个 | M1 | D2

2 |一个 | M2 | D3

2 |乙| M2 | D3

等等……

【讨论】:

  • 感谢您的建议。难道我们不能通过在 Division 模型的 name 字段中添加“blank=True”来避免添加另一个模型吗?
  • @ohid - 也许是这样,但我认为这是反映您的模型的方式,因为它是您想要的真正意图(至少我理解的方式:))
  • 好的,我试试看。
【解决方案2】:

如果我从您的评论中很好地理解了您,那么您的问题中列出的级别将超过这三个(组,部委,部门)。在这种情况下,对您来说最简单的方法可能是只使用一张表,其中您将保存组的名称和其他属性以及 parent_id - 包含它的组的 ID。所以它看起来像这样:

   from django.db import models

   class Group(models.Model):
       name = models.CharField(max_length=8, unique=True)
       slug = models.SlugField(max_length=8, unique=True,
        help_text='A label for URL config.')
       parent = models.ForeignKey(Group, null=True)
       #Other fields of the model...You could define attributes like
       #level which would define on which level is this group  
       #boolean attribute representing whether this group is leaf element or not and others

通过这样做,您可以使用 3 个表定义更多的 3 个层次结构级别。 因此,在这种情况下,所有条目都将分配给它们 parent_id(顶级实例除外 - 或在您的示例中 Group 1、Group2、Group3) 因此,例如,在您的示例中列出“组 1”的所有子组的 SQL 查询将是:

    SELECT g1.name AS level1, g2.name as level2, g3.name as level3
    FROM groups AS g1
    LEFT JOIN groups AS g2 ON g2.parent_id = g1.id
    LEFT JOIN groups AS g3 ON g3.parent_id = g2.id
    WHERE g1.name = 'Group 1';

有关此方法的更多信息,请查看https://en.wikipedia.org/wiki/Adjacency_list

您可以在这里使用的另一种方法是闭包表,您可能想看看这个: http://technobytz.com/closure_table_store_hierarchical_data.html

希望这对您有所帮助,祝您好运!

【讨论】:

  • 您是否建议使用 django-mptt。当我使用 mptt 时,表结构发生了变化。请参阅我的编辑以进行澄清。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-05
  • 2021-05-01
  • 1970-01-01
  • 2012-05-21
相关资源
最近更新 更多