如何在 Django 中这个特定的多对多关系中正确使用模板标签?

How to correctly use template tags in this specific Many-to-Many relationship in Django?

我通过模型设置获得了以下 Django 多对多,但我似乎无法弄清楚如何遍历每个 Container,获取列表复选框的数量以及这些复选框是真还是假 (CheckboxStatus.status)。

模型是:

class Container(models.Model):
    name = models.CharField(max_length=200)
    checkboxes = models.ManyToManyField('Checkbox',
                                        through='CheckboxStatus',
                                        related_name='containers')

class Checkbox(models.Model):
    name = models.CharField(max_length=60)
    description = models.CharField(max_length=200)
    order = models.PositiveSmallIntegerField(default=0)

class CheckboxStatus(models.Model):
    container = models.ForeignKey(Container,
                                          related_name='checkboxstatus')
    checkbox = models.ForeignKey(Checkbox, related_name='checkboxstatus')
    status = models.NullBooleanField()

我有以下内容,其中 object_list = CheckboxStatus 模型 ...

{% for object in object_list. %}
    {{ object.container }}
    {{ object.checkbox }}
    {{ object.status }}
{% endfor %}

...但这会产生所有复选框,我需要对每个 Container 进行一些操作。在伪代码中,我想要:

for container in object_list (where objectlist is "container"):
    container.id
    container.checkbox.id
    container.checkbox.status (unique for the container.id)

但也许这种关系完全错误。有人能把我推向正确的方向吗?

我修好了。

型号代码:

class ContainerBox(models.Model):
    name = models.CharField(max_length=200)

class CheckBox(models.Model):
    name = models.CharField(max_length=60)
    containerbox = models.ManyToManyField(
        ContainerBox, through="CheckBoxStatus")

class CheckboxStatus(models.Model):
    containerbox = models.ForeignKey(ContainerBox, on_delete=models.CASCADE)
    checkbox = models.ForeignKey(CheckBox, on_delete=models.CASCADE)
    status = models.NullBooleanField()

和模板代码:

{% for containerbox in object_list %}
    <h2>name: {{containerbox.name}}</h2>

    {% for checkboxstatus in containerbox.checkboxstatus_set.all %}
        {{ checkboxstatus.status}} ({{ checkboxstatus.checkbox }})<br/>

    {% endfor %}
{% endfor %}

这完成了我需要它做的事情:遍历容器,然后遍历复选框。我只是交换了复选框和复选框状态。

如果我没理解错的话,我认为您不需要通过 table。您应该能够定义 ManyToManyField and then use a ModelForm and a CheckboxSelectMultiple 小部件以将选项显示为复选框。

我将模型更改为:

class Container(models.Model):
    name = models.CharField(max_length=200)
    options = models.ManyToManyField('Option')

# I changed the name of the Checkbox model to Option, for clarity.
class Option(models.Model):
    name = models.CharField(max_length=60)
    description = models.CharField(max_length=200)
    order = models.PositiveSmallIntegerField(default=0)

来自 forms.py:

class ContainerOptionsForm(forms.ModelForm):
class Meta:
    model = Container
    fields = ['options']

    widgets = {
        'options': forms.CheckboxSelectMultiple(),
    }

在您的模板中包含选项表单字段:

{{ form.options }}

如果您需要更多地控制选项复选框的显示,您可以遍历表单的选项字段:

{% for checkbox in form.options %}
    <label>{{ checkbox.choice_label }} {{ checkbox.tag }}</label>    
{% endfor %}

这应该可以处理页面上的单个容器。如果您需要在同一页面上处理多个容器,则需要查看 ModelFormSet.