【问题标题】:Django ChoiceField or TypedChoiceField and invalid choice of idDjango ChoiceField 或 TypedChoiceField 和无效的 id 选择
【发布时间】:2011-12-13 12:02:09
【问题描述】:

我正在 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 之间的转换有关。能解释一下吗?

【问题讨论】:

    标签: django choicefield


    【解决方案1】:

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

    forms.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'))
    

    views.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 的新手有所帮助。请随时提及改进上述代码的任何方法...

    【讨论】:

      【解决方案2】:

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

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

      只需使用:

      category = forms.ModelChoiceField(model=Category)
      

      在您的表单定义中。

      【讨论】:

        猜你喜欢
        • 2011-04-10
        • 1970-01-01
        • 2018-10-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-09
        • 1970-01-01
        相关资源
        最近更新 更多