我正在尝试构建一个表单,但我不确定应该如何正确完成。这些是我的模特:
class Country(models.Model):
name = models.CharField(max_length=250, null=False, blank=False, unique=True)
twocode = models.CharField(max_length=5, null=False, blank=False, unique=True)
class GeoBonus(models.Model):
name = models.CharField(max_length=250)
country = models.ForeignKey(Country, related_name='geo_bonuses')
bookmaker = models.ForeignKey(Bookmaker, related_name='geo_bonuses')
博彩公司有奖金,每个国家都有所不同。例如:
Bookmaker has bonuses:
Slovakia: "eligible for 100% up to $200"
Afghanistan: "eligible for 100% up to €100!"
USA: "restricted country"
...
我想在GeoBonus中将文字保存为name
。当然我可以用简单的模型形式写,但我会提交表格248次(每个国家)。我想展示每个国家的所有领域。
我尝试手动为国家/地区创建新字段:
<form method="post" action="" class="wide">
{% csrf_token %}
{%bootstrap_form form %}
<div class="form-group">
{%for country in countries%}
<label class="control-label" for="{{country.twocode}}">{{country}}</label>
<input class="form-control" id="{{country.twocode}}" maxlength="250" type="text" />
{%endfor%}
</div>
<input type="submit" class="btn btn-default" name="submit" value="Save">
</form>
使用此forms.py类:
class GeoBonusForm(forms.ModelForm):
class Meta:
model = GeoBonus
fields = ['bookmaker']
但request.POST
确实只包含博彩公司字段。
EDIT1:Views.py
@staff_member_required
def geo_bonus_edit(request, bookmaker=None):
template = loader.get_template('geobonus/edit.html')
if request.method == 'POST':
form = GeoBonusForm(request.POST)
print request.POST
else:
form = GeoBonusForm()
context = RequestContext(request, {
'form': GeoBonusForm,
'countries': Country.objects.all(),
})
return HttpResponse(template.render(context))
答案 0 :(得分:1)
我建议您动态生成表单中的字段。它看起来像这样:
class GeoBonusForm(forms.ModelForm):
countries = Country.objects.all()
def __init__(self, *args, **kwargs):
super(GeoBonusForm, self).__init__(*args, **kwargs)
for country in self.countries:
self.fields[country.name] = forms.CharField()
这允许您为您拥有的每个国家/地区生成CharField。
因此,保存与正常的ModelForm有点不同我会建议覆盖save
方法:
def save(self, commit=True):
super(GeoBonusForm, self).save(commit=False)
bookmaker = Bookmaker.objects.get(id=self.cleaned_data['bookmaker'].id)
for field in self.cleaned_data:
if field != 'bookmaker':
country = Country.objects.get(name=field)
geo_bonus, created = GeoBonus.objects.get_or_create(bookmaker=bookmaker, country=country)
geo_bonus.name = self.cleaned_data[field]
geo_bonus.save()
首先,我们尝试选择博彩公司。之后,我们遍历已清理的字段(有关表单清理的更多信息,请查看here)并尝试get_or_create
GeoBonus
对象。现在我们只需填写相应country
字段的值并保存即可。
我稍微修改了你的观点代码:
def index(request, bookmaker=None):
template = loader.get_template('geobonus/edit.html')
if request.method == 'POST':
form = GeoBonusForm(request.POST)
if form.is_valid():
form.save()
else:
form = GeoBonusForm()
context = RequestContext(request, {
'form': GeoBonusForm,
})
return HttpResponse(template.render(context))
您不再需要将国家/地区传递给上下文,因为我们会在表单中生成字段。在POST
,我们检查表单是否有效并保存,如果是。
对于模板,您现在只需要这样:
<form action="." method="post">
{% csrf_token %}
{{ form }}
<input type="submit">
</form>
希望我做对了,这解决了你的问题。
编辑:注意,这是一个简单的快速示例。当然,您应该清理数据并检查输入是否有效,并准备好进行更简单的保存过程。
答案 1 :(得分:0)
你可以使用Django的inlinemodelformset,参考using a formset in views and templates代码示例。