0

我正在 Django 中编写一个简单的表单,其中包括一个 ChoiceField 允许用户从类别列表中进行选择。当然,我想传递要处理的 category_id。这是我的代码:

模型.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

表格.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 之间的转换有关。你能解释一下吗?

4

2 回答 2

2

出于某种原因,您将呈现表单的视图(包括添加选项)和处理提交的视图分开。您不会在提交时添加选项,因此这些值当然不会有效。

你应该完全摆脱这种add_product_form看法。您可以将form.fields['category'].choices...位移动到add_product视图中,但更好的解决方案是使用专门设计用于从模型或查询集中获取选择的表单字段 - 即ModelChoiceField.

只需使用:

category = forms.ModelChoiceField(model=Category)

在您的表单定义中。

于 2011-10-23T09:49:48.930 回答
0

谢谢丹尼尔。不久前我开始学习 Django,我有添加视图来显示表单的倾向,这不是必需的。所以是的,我摆脱了add_product_form并完全依赖add_product。至于类别选择字段,现在它在 forms.py 中的编码如下:

表格.py:

from django import forms
from django.utils.translation import ugettext_lazy as _

from myapp.models import Category

class AddProductForm(forms.Form):
    category = forms.ModelChoiceField(label=_('Category'), queryset=Category.objects.all())
    product = forms.CharField(label=_('Product'), widget=forms.TextInput())
    code = forms.CharField(label=_('Code'), widget=forms.TextInput())
    price = forms.DecimalField(label=_('Price'))

视图.py:

def add_product(request):
   if request.method == 'POST':
      form = AddProductForm(request.POST)

      if form.is_valid():
         category = request.POST['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()

         # redirect to 'ms-admin/category_id' (the category to which belongs the newly added product
         return HttpResponseRedirect('/ms-admin/'+category)
     else:
         form = AddProductForm()

     return render_to_response('product-form.html', {'form':form})

我希望这对 django 的新手有所帮助。请随时提及改进上述代码的任何方法...

于 2011-10-23T17:44:40.557 回答