如何在django的多人关系中为每个外键创建一个表单字段

时间:2018-04-02 12:07:02

标签: python django django-forms

我不明白如何在Django中构建特定的表单。

首先,这是我的模特:

class Category(models.Model):
    name = models.CharField(max_length=200, unique=True)


class Assessment(models.Model):
    name = models.CharField(max_length=200)
    pub_date = models.DateTimeField(verbose_name=_('date published'), default=timezone.now)
    classgroup = models.ForeignKey(ClassGroup, verbose_name=_('class'), on_delete=models.CASCADE, related_name='+')
    category = models.ManyToManyField(Category, through='AssessmentScale', through_fields=('assessment', 'category'),)
    total = models.IntegerField()


class AssessmentScale(models.Model):
    assessment = models.ForeignKey(Assessment, on_delete=models.CASCADE)
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    value = models.IntegerField()

我希望有一个像html form这样的表单。实际上,评估量表被细分为不同的类别。因此,当我创建评估时,我希望每个类别都有一个表单字段,允许通过我的自定义中介模型AssessmentScale添加值。但我真的不知道建立这种形式的django方式。我读了这个post,我认为类似,有人建议使用内联模型表格集。但我不明白如何用后者来解决我的问题。你能帮帮我吗?

1 个答案:

答案 0 :(得分:0)

我没有得到Stackoverflow的回答,但是我的一个朋友用内联formset解决了我的问题:

# forms.py
class AssessmentForm(ModelForm):
    class Meta:
        model = Assessment
        exclude = ('category',)


CategoryAssessmentFormSet = inlineformset_factory(
    Assessment,
    Assessment.category.through,
    fields=['category', 'value'],
    can_delete=False,
    extra=Category.objects.count(),
    max_num=Category.objects.count(),
    widgets={'category': Select(attrs={'hidden': 'true'})}
)

在我看来,要渲染formset:

# views.py
initial = [{'category': category} for category in Category.objects.all()]
formset = CategoryAssessmentFormSet(initial=initial)

选择已隐藏,但我仍然需要所选字段的名称,在我的模板中:

# template
{{ formset.management_form }}
{% for form in formset %}
    <div class="p-2">
        {% for value,selected in form.fields.category.choices %}
            {% if value == form.category.value %}{{ selected }}{% endif %}
        {% endfor %}
        {{ form.category }}
    </div>
    <div>
        {{ form.value}}
    </div>
{% endfor %}