Django 多对多字段
Posted
技术标签:
【中文标题】Django 多对多字段【英文标题】:Django ManyToMany Field 【发布时间】:2013-04-27 22:24:13 【问题描述】:我需要制作一个智能菜单,为此我需要一个多对多关系。
我的模型是:
from django.db import models
class Health_plan(models.Model):
a = models.IntegerField ()
b = models.IntegerField ()
class Doctors_list(models.Model):
name = models.CharField(max_length=30)
hp_id = models.ManyToManyField(Health_plan)
def __unicode__(self):
return self.name
如何在数据库中建立这种关系?我正在考虑将health_plans
(a,b) 作为列,将医生作为行,用 0 和 1 来标识他们所涵盖的健康计划。
有人告诉我这是滥用ManyToManyField
,我不知道该怎么做。
帮助赞赏
【问题讨论】:
【参考方案1】:Django 为您创建表格。在您的项目文件夹中运行:
python manage.py syncdb
Health_plan 和 Doctors_list 都是表。 “a”和“b”是 Health_plan 中的列。 'Name' 和 'hp_id' 是 Doctors_list 中的列。 Django 将在每个表中为 id 创建一个列。 Django 还会创建一个表“Doctor_list_Health_plan”来存储关系信息。
Django 模型是 Python 类,因此适用 Python 命名约定。使用 HealthPlan 和 Doctor(CapitalizeWord 单数)。
您的字段名称有点抽象。我建议您使用更具描述性的名称。例如:
class HealthPlan(models.Model):
name = models.CharField()
extra_care = models.BooleanField()
【讨论】:
【参考方案2】:Django 的 ORM 已经处理了中间表,因此您不必“在数据库中建立这个关系(船)”,但鉴于您的问题,您显然需要了解正确的关系模型规范化 - 如果您不这样做'不了解关系模型,使用 Django 的 ORM 和任何其他 sql 东西 FWIW 都将一事无成。
为了记录,在关系模型中,多对多关系被建模为在其他两个表上都有外键的关系(SQL 中的“表”),即:
health_plan(#health_plan_id, name, ...)
doctor(#doctor_id, firstname, lastname, ...)
doctors_health_plans(#health_plan_id, #doctor_id)
所以你的 django 模型应该是:
class HealthPlan(models.Model):
# no need to define an 'id' field,
# the ORM provides one by default
name = models.CharField(....)
class Doctor(models.Model):
firstname = models.CharField(....)
lastname = models.CharField(....)
health_plans = models.ManyToManyField(HealthPlan, related_name="doctors")
然后您就可以获得医生的所有健康计划:
doc = Doctor.objects.get(pk=xxxx)
doc.health_plans.all()
和健康计划的所有医生:
plan = HealthPlan.objects.get(pk=xxxx)
plan.doctors.all()
FineManual(tm) 像往常一样是你的朋友...
【讨论】:
【参考方案3】:将health_plans
列为列的方法不一定是错误的,但这意味着您拥有固定数量的健康计划,并且您永远不会添加新计划。
关系数据库中多对多关系的传统方法是在中间引入一个表。此表将仅包含医生和健康计划之间的关联。
如果您有一个 Doctor
表,其中包含:
id name
1 foo
2 bar
还有一个HealthPlan
表:
id model
1 a
2 b
然后添加一个表格Doctor_HealthPlan
,如下所示:
doctor_id healthplan_id
1 2
2 1
2 2
django 中的ManyToMany
字段类型会自动为您创建此表。您的代码是正确的,但您可能应该将 hp_id
重命名为 health_plans
,因为它是一个代理,可让您访问与医生相关的健康计划列表。
【讨论】:
所以在我的健康计划表上我只做:class Health_plan(models.Model): name = models.Charfield (max_lenght=10)
----> 并且在一个医生 ID 的连接表上我放了多个健康计划 ID?
连接表由django管理。您的Health_Plan
应包含一个姓名,您的医生应包含一个绑定到Health_Plan
的ManyToMany
字段。【参考方案4】:
您只需先保存两个模型,然后将 healthplan 实例添加到医生列表中。 Django 将为您处理剩下的事情。
例如:
doctor_list = Doctors_list(name="Bwire")
health_plan.save()
doctor_list.save()
#Then add the plan to the doctors list.
doctor_list.hp_id.add(health_plan)
【讨论】:
以上是关于Django 多对多字段的主要内容,如果未能解决你的问题,请参考以下文章