Django模型中的ManyToManyField

时间:2018-12-05 10:53:09

标签: django django-models django-forms django-admin

我需要创建一组这样的模型:

df.B.shift(1)

问题是我希望场景按我指定的顺序包含多个步骤,甚至同一步骤也要多次。像这样:

class Step(models.Model):
    field1 = models.CharField(max_length=50)
    field2 = models.CharField(max_length=50)

class Scenario(models.Model):
    name = models.CharField(max_length=50)
    steps = models.ManyToManyField(Step, related_name="scenarios")

我希望此步骤的命令在管理站点中易于编辑。 我发现了Scenario1: step1 step2 step1 step3 ,它看起来很像我在管理站点中所需要的,但是它没有选择再增加一次时间和上下移动步骤。

1 个答案:

答案 0 :(得分:1)

计算机科学中有一句话说:“ indirection 可以解决计算机科学中的所有问题”-戴维·惠勒(David Wheeler)。

在这种情况下,您应该使用“通过”表,例如:

class Step(models.Model):
    field1 = models.CharField(max_length=50)
    field2 = models.CharField(max_length=50)

class Scenario(models.Model):
    name = models.CharField(max_length=50)
    steps = models.ManyToManyField(
        Step,
        through='ScenarioStep',
        related_name="scenarios"
    )

class ScenarioStep(models.Model):
    scenario = models.ForeignKey(
        'Scenario',
        on_delete=models.CASCADE,
        related_name='scenariostep'
    )
    step = models.ForeignKey(
        'Step'
        on_delete=models.CASCADE,
        related_name='scenariostep'
    )
    order = models.PositiveIntegerField()

    class Meta:
        ordering = ['order']

因此,我们在这里引入了一个额外的模型,该模型替换了ManyToManyField已经构造的隐藏“通过表”。

假设有一个Scenario记录,那么Step有一个ScenarioStep,我们通过一个Order字段对其进行排序。

例如,我们可以使用以下命令将给定的步骤添加到scenario中:

s1 = Step.objects.create(field1='step1')
s2 = Step.objects.create(field1='step1')
s3 = Step.objects.create(field1='step1')

sc1 = Scenario.objects.create(name='Scenario1')

ScenarioStep.objects.create(order=1, scenario=sc1, step=s1)
ScenarioStep.objects.create(order=2, scenario=sc1, step=s2)
ScenarioStep.objects.create(order=3, scenario=sc1, step=s1)
ScenarioStep.objects.create(order=4, scenario=sc1, step=s3)

然后,我们可以使用以下步骤迭代这些步骤:

for step in sc1.steps.order_by('scenariostep'):
    # ... (do something with the step)
    pass