我正在制作django应用程序而我正面临一个问题。我正在尝试定义一个模型,其中一个ForeignKey
将取决于另一个ForeignKey
。
我的申请是关于做出选择。
因此,假设您有decision
,decision
有多个choice
,而choice
有status
(因为其他约束)。
status
可用于多个choices
,但status
只能与一个decision
相关,choice
与,____________, ,____________,
| | 1, n 1, 1 | |
| Decision |------------------| Status |
|____________| |____________|
| |
| 1, n | 1, n
| |
| 1, 1 |
,_____|______, |
| | 1, 1 |
| Choice |-------------------------'
|____________|
相同到。
它不是固定的,如果需要可能会更改:
class Decision (models.Model):
name = models.CharField (max_length = 63)
class Status (models.Model):
value = models.CharField (max_length = 63)
decision = models.ForeignKey (Decision)
class Choice (models.Model):
name = models.CharField (max_length = 63)
decision = models.ForeignKey (Decision)
status = models.ForeignKey (Status, limit_choices_to = {'decision' : decision})
这是我当前的(简化的)( not working )代码:
limit_choices_to = {'decision' : decision}
这里的重要部分是{{1}}。
我发现另一个SO问题(In django, how to limit choices of a foreignfield based on another field in the same model?)处理同一个问题,但问题是变老,最好的答案是依赖外部应用程序(django-smart-selects)。
我宁愿不必使用外部的东西,我也不明白为什么只使用Django就无法解决像3表关系这样简单的东西!
如果有人有任何解决方案或任何建议,请告诉我。
答案 0 :(得分:3)
你所要求的是不可能的,至少不在你设定的范围内(没有形式,没有外部库)。 status
模型的Choice
字段是外键,两个表之间的关系...它不处理过滤本身,简单地说 - 它没有此功能。这不是 django 的事情,这是数据库的事情。 Django ORM并不像您想象的那样远离数据库,它很精彩,但它并不神奇。
一些可用的解决方案是:
save
,在那里添加检查,如果失败则抛出错误status
属性,并在设置如果您使用FormField
方法以及覆盖save
,您将获益于知道Choice
无法保存,但它违反了此限制用户的结尾(填写表单)或后端(在.save()
实例上调用Choice
的代码。
答案 1 :(得分:1)
我不熟悉Django,但是如果你试图解决“同一个选择与问题相关的部分问题”,那就是如何在数据库级别完成它:
请注意识别关系的用法,因此DecisionId
将在“分支”下向下迁移,并在“底部”合并。因此,如果Choice
有Status
,则它们都必须链接到同一Decision
。
答案 2 :(得分:1)
我认为你需要的是through
模型,如下所示:
class Choice (models.Model):
name = models.CharField (max_length = 63)
status = models.ForeignKey(Status)
decision = models.ForeignKey(Decision)
class Status(Models.Model):
name = models.CharField(max_length=20)
class Decision(models.Model):
name = models.CharField(max_length = 63)
choices = models.ManyToManyField(Status, through = "Choice")
这样,每个决策都有很多选择,每个选择只有一个状态。您可以执行以下查询:
my_decision.choices.all()
或my_status.decision_set.all()
我建议您查看documentation以获取有关如何使用模型的示例
答案 3 :(得分:0)
在以下语句中,decision
既不是可调用对象,也不是models.Q
对象:
status = models.ForeignKey (Status, limit_choices_to = {'decision' : decision})
这是一种表示数据的方法:
class Decision(models.Model):
...
# a status is relevant for only one decision
# there may be more than one Status per Decision.
class Status(Models.Model):
decision = models.ForeignKey(Decision)
# each choice is linked to one decision and has a status.
class Choice (models.Model):
status = models.ForeignKey(Status)
# if status is mandatory, then you can get the decision
# from status.decision. per se, this fk could be optional.
decision = models.ForeignKey(Decision)
这是另一个:
class Decision(models.Model):
...
# a decision has multiple choices
# a choice pertains to only one decision
class Choice (models.Model):
decision = models.ForeignKey(Decision)
# each status is relevant to one decision
# and may encompass multiple choices.
class Status(Models.Model):
decision = models.ForeignKey(Decision)
# problem with this representation is that this allows for
# a choice to be linked to multiple statuses.
# this happens when using M2M instead of ForeignKey.
choices = models.ManyToManyField(Choice)