Django 1.8:表单未渲染多对多字段的原因及渲染方法
问题分析与解决办法
嘿,我来帮你排查下这个表单字段没渲染的问题,主要有两个关键错误:
1. 表单字段类型用错了
你写的SummaryForm继承自forms.Form(普通表单),但里面的transcripts用了模型字段models.ManyToManyField——这是不对的!普通表单类里应该用表单专属的字段类型,对应多对多模型的表单字段是forms.ModelMultipleChoiceField。
2. Meta类里的字段名拼写错误
你在widgets里写的是'transcript'(单数),但你的字段名是transcripts(复数),这会导致widget配置不生效,甚至字段无法被正确识别。
修正后的代码
把forms.py改成下面这样:
from django import forms from .models import Transcript class SummaryForm(forms.Form): size = forms.CharField(label='size', max_length=50, required=False) # 替换成表单专用的ModelMultipleChoiceField transcripts = forms.ModelMultipleChoiceField( queryset=Transcript.objects.all(), # 指定要选择的模型数据集合 blank=True, widget=autocomplete.ModelSelect2Multiple(url='tr-autocomplete') )
如果你想保留Meta类的写法,注意字段名要对应:
from django import forms from .models import Transcript class SummaryForm(forms.Form): size = forms.CharField(label='size', max_length=50, required=False) transcripts = forms.ModelMultipleChoiceField( queryset=Transcript.objects.all(), blank=True ) class Meta: widgets = { # 字段名要和上面定义的一致,是transcripts(复数) 'transcripts': autocomplete.ModelSelect2Multiple(url='tr-autocomplete'), }
模板渲染方法
在模板里和普通表单字段一样渲染就行,比如:
<form method="post"> {% csrf_token %} {{ form.size }} {{ form.transcripts }} <!-- 这里就能正确渲染多对多选择框了 --> <button type="submit">提交</button> </form>
或者直接用{{ form.as_p }}、{{ form.as_table }}这类快捷方式渲染整个表单。
内容的提问来源于stack exchange,提问作者max
相关产品推荐
相关产品推荐

