可在字段集中使用的有序ManyToManyField

2024-10-01 17:38:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在使用一个有序的ManyToManyField小部件,并且它的前端工作良好:

alt text

不幸的是,我有很多麻烦让后端工作。连接后端的最明显的方法是使用一个through表,在关系的两边用ForeignKey键控一个模型,然后覆盖save方法。这将非常有效,除了由于内容的特殊性,绝对要求将这个小部件放在一个字段集中(使用ModelAdminfieldsets属性),即apparently not possible。在

我没主意了。有什么建议吗?在

谢谢!在


Tags: 方法模型内容属性关系部件savenot
1条回答
网友
1楼 · 发布于 2024-10-01 17:38:53

关于如何设置模型,您是正确的,带有“order”列的through表是表示它的理想方式。Django不允许您在字段集中引用这种关系,这也是正确的。解决这个问题的诀窍是记住您在ModelAdmin的“fieldsets”或“fields”中指定的字段名实际上并不是指Model的字段,而是指ModelForm的字段,我们可以随心所欲地覆盖这些字段。有很多领域,这很棘手,但请容忍我:

假设你试图代表比赛和竞争对手,在比赛和竞争者之间有一个有序的多人,其中顺序代表竞争者在比赛中的排名。您的models.py将如下所示:

from django.db import models

class Contest(models.Model):
    name = models.CharField(max_length=50)
    # More fields here, if you like.
    contestants = models.ManyToManyField('Contestant', through='ContestResults')

class Contestant(models.Model):
    name = models.CharField(max_length=50)

class ContestResults(models.Model):
    contest = models.ForeignKey(Contest)
    contestant = models.ForeignKey(Contestant)
    rank = models.IntegerField()

希望这和你所面对的相似。现在,对管理员来说。我已经写了一个例子admin.py,其中有大量的注释来解释发生了什么,但是下面的总结可以帮助您:

因为我没有您编写的有序m2m小部件的代码,所以我使用了一个占位符虚拟小部件,它只是从TextInput继承的。输入包含一个逗号分隔的参赛者id列表(没有空格),它们在字符串中的出现顺序决定了它们在ContestResults模型中“rank”列的值。在

所发生的情况是,我们用我们自己的重写Contest的默认ModelForm,然后在其中定义一个“results”字段(我们不能将该字段称为“competitors”,因为这将与模型中的m2m字段发生名称冲突)。然后我们重写__init__(),当表单在管理中显示时调用它,这样我们就可以获取已经为竞赛定义的任何竞赛结果,并使用它们填充小部件。我们还重写save(),这样我们就可以从小部件中获取数据并创建所需的竞争结果。在

注意,为了简单起见,这个例子省略了一些事情,比如验证小部件中的数据,因此如果您试图在文本输入中输入任何意外的内容,那么事情就会中断。另外,创建竞赛结果的代码非常简单,可以大大改进。在

我还应该补充一点,我已经实际运行了这段代码并验证了它是否有效。在

^{pr2}$

如果你想知道,我自己在一个项目中遇到了这个问题,所以大部分代码都来自这个项目。希望你觉得有用。在

相关问题 更多 >

    热门问题