Django ChoiceField 或 TypedChoiceField 以及无效的 id 选择
我正在 Django 中编写一个简单的表单,其中包含一个 ChoiceField ,允许用户从类别列表中进行选择。当然我想传递要处理的category_id。这是我的代码:
models.py:
class Category(models.Model):
category = models.CharField(max_length=128)
def __unicode__(self):
return self.category
class Product(models.Model):
code = models.CharField(max_length=75)
name = models.CharField(max_length=128)
price = models.DecimalField(max_digits=7, decimal_places=2)
category = models.ForeignKey(Category)
def __unicode__(self):
return self.name
forms.py
class AddProductForm(forms.Form):
category = forms.ChoiceField(label=_('Category'))
product = forms.CharField(label=_('Product'), widget=forms.TextInput())
code = forms.CharField(label=_('Code'), widget=forms.TextInput())
price = forms.DecimalField(label=_('Price'))
现在在views.py 中我填写了选项:
def add_product_form(request):
form = AddProductForm()
form.fields['category'].choices =[(c.id, c.category) for c in Category.objects.all()]
return render_to_response('product-form.html', {'form':form})
现在一切似乎都很好,除了当我提交表单时。它抱怨类别的 ID。它说: 选择一个有效的选项。 1 不是可用选项之一
这就是我处理表单的方式:
def add_product(request):
if request.method == 'POST':
form = AddProductForm(request.POST)
if form.is_valid():
category = request.cleaned_data['category']
product = form.cleaned_data['product']
code = form.cleaned_data['code']
price = form.cleaned_data['price']
product = Product(code=code, name=product, price=price, category_id=category)
product.save()
return HttpResponseRedirect('/ms-admin/')
else:
form = AddProductForm() # more is required here to fill the choices again
return render_to_response('product-form.html', {'form':form})
我对 TypedChoiceField 进行了相同的尝试,但得到了相同的无效数据。我知道这与 string 和 int 之间的转换以及 unicode 的东西有关。你能解释一下吗?
I am writing a simple form in Django which includes a ChoiceField allowing users to choose from a list of categories. For sure I want to pass the category_id to be processed. This is my code:
models.py:
class Category(models.Model):
category = models.CharField(max_length=128)
def __unicode__(self):
return self.category
class Product(models.Model):
code = models.CharField(max_length=75)
name = models.CharField(max_length=128)
price = models.DecimalField(max_digits=7, decimal_places=2)
category = models.ForeignKey(Category)
def __unicode__(self):
return self.name
forms.py
class AddProductForm(forms.Form):
category = forms.ChoiceField(label=_('Category'))
product = forms.CharField(label=_('Product'), widget=forms.TextInput())
code = forms.CharField(label=_('Code'), widget=forms.TextInput())
price = forms.DecimalField(label=_('Price'))
Now in the views.py I fill in the choices:
def add_product_form(request):
form = AddProductForm()
form.fields['category'].choices =[(c.id, c.category) for c in Category.objects.all()]
return render_to_response('product-form.html', {'form':form})
Now everything seems to be okay except when I submit the form. It complains about the IDs of the Category. It says:
Select a valid choice. 1 is not one of the available choices
This is how I am processing the form:
def add_product(request):
if request.method == 'POST':
form = AddProductForm(request.POST)
if form.is_valid():
category = request.cleaned_data['category']
product = form.cleaned_data['product']
code = form.cleaned_data['code']
price = form.cleaned_data['price']
product = Product(code=code, name=product, price=price, category_id=category)
product.save()
return HttpResponseRedirect('/ms-admin/')
else:
form = AddProductForm() # more is required here to fill the choices again
return render_to_response('product-form.html', {'form':form})
I tried the same with TypedChoiceField but got the same invalid data. I know it has to do with the conversion between string and int and the unicode stuff. Can you please explain?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
由于某种原因,您将呈现表单的视图(包括添加选项)与处理提交的视图分开。您不会在提交时添加选项,因此这些值当然不会有效。
您应该完全删除
add_product_form
视图。您可以将form.fields['category'].choices...
位移动到add_product
视图中,但更好的解决方案是使用专门设计的表单字段用于从模型或查询集中获取选择 - 即ModelChoiceField
。使用:即可。
只需在表单定义中
For some reason, you've separated the view that renders the form - including adding the choices - and the view that processes the submission. You don't add the choices on submission, so of course the values are not going to be valid.
You should get rid of the
add_product_form
view altogether. You could move theform.fields['category'].choices...
bit into theadd_product
view, but a better solution is to use the form field that's specifically designed for getting choices from a model or queryset - ieModelChoiceField
.Just use:
in your form definition.
谢谢丹尼尔。我不久前开始学习Django,我有这种倾向添加视图来显示表单,这是没有必要的。所以,是的,我摆脱了 add_product_form 并仅依赖 add_product。至于类别选择字段,现在它在 forms.py 中的编码如下:
forms.py:views.py
:
我希望这对 django 新手有所帮助。请随意提及改进上述代码的任何方法......
Thanks Daniel. I started learning Django not long time ago and I have this tendency to add a view to display a form, which is not necessary. So yes, I got rid of add_product_form and relied solely on add_product. As for the Category choice field now it is coded like this in the forms.py:
forms.py:
views.py:
I hope this helps newcomers to django. Please feel free to mention any ways of improving this above code ...