我想在django中处理多个字段。在PHP中,我使用生成的HTML,如:
<input type="text" name="myfield[1]" />
<input type="text" name="myfield[4]" />
<input type="text" name="myfield[5]" />
括号中的数字是来自db(cookie或其他来源)的id
当我处理这个表单时,我可以通过键从$_POST['my field']
数组中获取值(例如,1,4,5)。
我想知道,我怎样才能在django中做同样的事情以及如何处理这样的多个字段? 我之前创建了一个复选框列表。在那里我可以将id存储在复选框字段的值中,但它不能与textfield一起使用,因为在值中我需要用户发送的值。
UPD:
我是Django和Python的新手(几周前刚刚开始使用Django)
楷模
from django.contrib.auth.models import User
class Order(models.Model):
category = models.ForeignKey(Category)
exhibition = models.ForeignKey(Exhibition)
user = models.ForeignKey(User)
date = models.DateField()
ordered = models.IntegerField()
class Exhibition(models.Model):
play = models.ForeignKey(Play)
date = models.DateTimeField()
class Category(models.Model):
name = models.CharField(max_length=30)
price = models.IntegerField()
total = models.IntegerField()
视图
from django.forms.models import modelformset_factory
from tickets.forms import CourierForm
def play_info_courier(request, pk):
data = get_object_or_404(Exhibition, pk=pk)
CourierFormSet = modelformset_factory(CourierForm, extra=0)
orders = Order.objects.filter(exhibition=data).values()
formset = CourierFormSet(initial=orders)
context = RequestContext(request, {'data': data, 'formset': formset})
return render_to_response('tickets/courier.html', context)
形式
class CourierForm(forms.ModelForm):
class Meta:
model = Order
HTML
<form method="post" action="">
{% csrf_token %}
{{ formset.management_form }}
<table class="table table-bordered table-hover">
{% for form in formset.forms %}
{% if forloop.first %}
<thead>
<tr>
{% for field in form %}
{% if field.name != 'id' %}
<th>{{ field.label|capfirst }}</th>
{% endif %}
{% endfor %}
</tr>
</thead>
{% endif %}
<tr>
<!-- here is my problem, how can I get username from User
or anything else from other related models? -->
<td>{{ form.user.username }}</td>
<td>{{ form.category.price }}</td>
<td>{{ form.date.value }}</td>
<td>{{ form.ordered }}</td>
</tr>
{% endfor %}
</table>
<input type="submit" name="order" value="Order"/>
<input type="submit" name="clean" value="Clean order"/>
</form>
答案 0 :(得分:1)
在Django中,您使用formsets来实现此类方案。
示例视图:
from django.shortcuts import render
from django import forms
from django.forms.formsets import formset_factory
class TestForm(forms.Form):
id = forms.IntegerField(label='id', widget=forms.HiddenInput)
value = forms.CharField(label='value')
TestFormSet = formset_factory(TestForm, extra=0)
def test(request):
if request.method == 'POST':
fs = TestFormSet(request.POST)
else:
fs = TestFormSet(initial=[
dict(id=1, value='foo'),
dict(id=4, value='bar'),
dict(id=5, value='baz'),
])
context = {
'fs': fs,
}
return render(request, 'formset/test.html', context)
formset/test.html
模板:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<form method="POST">{% csrf_token %}
{{ fs.management_form }}
{% for form in fs %}
{% for field in form %}
<div>{{ field }}</div>
{% endfor %}
<hr>
{% endfor %}
<button type="submit">Submit</button>
</form>
<hr>
{{ fs.cleaned_data }}
</body>
</html>
示例提交的数据(fs.cleaned_data
):
[
{
'id': 1,
'value': u'foo'
},
{
'id': 4,
'value': u'bar'
},
{
'id': 5,
'value': u'baz'
}
]
对于模型表单集,您cannot generally supply the initial
parameter与常规表单集一样 - initial
值仅适用于extra
表单,而不适用于与模型的实际实例关联的表单
执行此操作时:
orders = Order.objects.filter(exhibition=data).values()
formset = CourierFormSet(initial=orders)
你可能是这个意思:
orders = Order.objects.filter(exhibition=data)
formset = CourierFormSet(queryset=orders)
这将为Order.objects.filter(exhibition=data)
返回的所有实例的表单实例化一个表单集。之后,formset中的每个表单都将具有instance
属性,并保存绑定到该表单的实际Order
实例:
<td>{{ form.instance.user.username }}</td>
请注意,您的代码还存在其他一些问题:
{% if forloop.first %}
块内执行此操作;这不太可能是你真正想要实现的目标。id
字段;这将使您提交的表单数据与初始模型实例分离 - 您希望这些数据作为隐藏字段,在呈现id
字段时由表单集自动完成。modelformset_factory
的第一个参数应该是。{
model 类,而不是表单类;你可能意思是CourierFormSet = modelformset_factory(Order, form=CourierForm, extra=0)
。答案 1 :(得分:0)
尝试使用
request.POST.getlist('myfield')