Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 什么';这种数据库模型结构的最佳方法是什么?_Python_Django_Django Models - Fatal编程技术网

Python 什么';这种数据库模型结构的最佳方法是什么?

Python 什么';这种数据库模型结构的最佳方法是什么?,python,django,django-models,Python,Django,Django Models,我正在与Django一起开发一个物业管理系统,现在我正在开发一个名为“物业检查”的应用程序,其基本目的是提供一个表单,其中包含一个任务列表,如“洗碗机:清洁&清空?”,这些任务需要由工作人员在物业进行检查 其主要思想是允许管理员在管理员端创建任务及其类别。 示例:任务-洗碗水:清洁和清空属于类别-厨房 每个属性检查都属于一个属性,它具有任务列表,这些任务具有不同的状态,如“已检查”或“需要注意” 到目前为止,这就是我所创造的: 型号.py class Task(models.Model):

我正在与Django一起开发一个物业管理系统,现在我正在开发一个名为“物业检查”的应用程序,其基本目的是提供一个表单,其中包含一个任务列表,如“洗碗机:清洁&清空?”,这些任务需要由工作人员在物业进行检查

其主要思想是允许管理员在管理员端创建任务及其类别。 示例:任务-洗碗水:清洁和清空属于类别-厨房

每个属性检查都属于一个属性,它具有任务列表,这些任务具有不同的状态,如“已检查”或“需要注意”

到目前为止,这就是我所创造的:

型号.py

class Task(models.Model):
    name = models.CharField(db_column='SafetyTaskName', max_length=100, blank=False, null=False)
    category = models.ForeignKey(Categories, db_column='category')
    task_check = models.ForeignKey(TaskCheck)

class Categories(models.Model):
    name = models.CharField(db_column='Categories', max_length=40, null=False, blank=False)

class TaskCheck(models.Model):
    status = models.CharField(db_column='Status', choices=STATUS_CHOICES, default='nd')
    image = models.ImageField(upload_to='property_check',null=True)
    notes = models.CharField(db_column='Notes', max_length=500, blank=True, null=True)  # Field name made lowercase.

class Propertycheck(models.Model):
    property = models.ForeignKey(Property, models.DO_NOTHING, db_column='ID_Property')  # Field name made lowercase.
    task = models.CharField(TaskCheck)
    name = models.CharField(db_column='Name', max_length=150)
    date = models.DateField(db_column='Date', default=timezone.now)  # Field name made lowercase.
    next_visit = models.DateField(db_column='Next Visit')
    staff = models.ForeignKey(User, db_column='Staff', max_length=25)
    notes = models.CharField(db_column='Notes', max_length=500, blank=True, null=True)  # Field name made lowercase.
我假装的功能示例:

一名工作人员前往需要检查的房产,他填写 包含所有任务的窗体。如果需要更多的任务, 管理员进入管理面板并添加一个新的。同等地位 适用于每项任务

要求:

  • 一个财产有许多财产支票
  • 属性检查具有任务列表
  • 管理员必须能够添加任务和类别
  • 任务属于一类
  • 财产检查由一名工作人员进行
  • 每个属性的任务列表都是相同的
  • 每个任务都必须有一个状态(例如:已完成状态)
问题: 我有点不知道在哪里使用外键。我需要属性检查来显示任务列表,以及每个任务的状态

根据我的经验,我现在被困在这方面,所以我需要一些帮助。 你能看看我们做了什么,告诉我一个更好的解决方案吗

***更新***

多亏了Bruno Desthuilliers的回答,我可以按照他的建议重组我的模型。我认为这个解决方案更接近我需要的,但我的问题是,根据布鲁诺回答的要求,我的更改是否100%正确

class Task(models.Model):
    name = models.CharField(max_length=100)
    category = models.ForeignKey(Categories)
    property = models.ManyToManyField(Property)

class Categories(models.Model):
    name = models.CharField(max_length=40)

class TaskCheck(models.Model):
    status = models.CharField(choices=STATUS_CHOICES, default='nd')
    image = models.ImageField(upload_to='task_check', null=True)
    notes = models.TextField(max_length=500)
    task = models.ForeignKey(Task)
    property_check = models.ForeignKey(Propertycheck)

class Propertycheck(models.Model):
    property = models.ForeignKey(Property, models.DO_NOTHING)
    name = models.CharField(max_length=150)
    date = models.DateField(default=timezone.now)
    next_visit = models.DateField()
    staff = models.ForeignKey(User, max_length=25)
    notes = models.TextField(max_length=500, default='')
我的英语不是最好的,我不确定我的问题的最佳标题

一个财产有许多财产支票

这只描述了关系基数的一半——您还需要指定属性检查可以属于多少个属性。在这种情况下,答案似乎相当明显(我看不出相同的财产检查会属于多个财产的情况),但除非您对该领域有真正深入的工作知识,否则您仍然应该询问您的客户-有时“明显”的事情实际上是错的;-)

但是,如果我们认为“一个财产有很多财产检查”和“一个财产检查属于一个单一的财产”,我们有一对多的关系。在db模式级别,这是通过“多”端中“一”端的外键实现的,即PropertyCheck必须具有fk on属性

当您记住在关系模型中,字段是原子值(每个字段中只有一个值)时,这是合乎逻辑的。无法在Property中存储相关PropertyCheck id的列表,但可以在每个PropertyCheck中存储单个属性id

当您考虑约束时,这也是合乎逻辑的-一个属性实际上可以有“零到多”相关的属性检查(您可以有一个到目前为止从未“检查”过的属性),但PropertyCheck必须有一个相关的属性(在没有属性的情况下进行属性检查是没有意义的,不是吗?)。如果属性检查以列表形式存储在属性中的ID,您仍然可以在不使用属性的情况下创建属性检查(如果删除了属性检查且未更新属性的属性检查列表,您也会遇到一致性问题)

因此,长话短说:对于一对多关系,fk位于“多”端并指向“一”端

属性检查具有任务列表

你确定这个是对的吗?在我看来,您将应用程序的用户视图与数据库模式混淆了

当然,用户在“属性检查”页面上看到的是要执行的任务列表(以及每个任务的复选框等)——但这并不意味着任务属于属性检查。如果是这样,管理员必须为每个属性检查创建一个新的任务列表。。。就我对该领域的理解而言,关键是每个属性都有一个任务列表,系统为每个属性检查构建一个(尚未检查)任务检查列表。哪个FWIW已经是您开始设计的

所以(假设我的问题是对的),您的规则实际上是“每个属性都有一个任务列表”。现在我们还有另一个基数需要整理:一个任务是属于一个属性,还是同一个任务可以由多个属性共享

我们已经介绍了第一个案例(参见上文)。在第二种情况下——实际上更可能是因为对于大多数属性来说,肯定有相当多的任务是相同的——您有一个多对多的关系。这些由关系表具体化,该关系表在关系的每一侧都有一个fk,对fk具有唯一性约束(您不希望为同一属性列出两次相同的任务)。请注意,使用Django的ORM,您不需要为此明确声明一个模型(当然,除非您需要向关系中添加其他字段,但到目前为止,我认为这里没有必要这样做)-只需在关系的任何一侧声明一个多个字段(其实并不重要),ORM就会为您创建中间表

然后,在属性检查和任务检查之间就有了关系。这里是一个简单的一对多关系——一个属性检查有许多任务检查,一个任务检查属于一个属性检查。这里唯一的限制是,这些任务检查的任务必须与属性检查的属性属于同一个属性(是)