3

我以前使用过这段代码,它工作得很好,另一个成员建议我使用 ModelForm,使用 form.is_valid() 函数等确实有意义。所以想试一试。

我浏览了互联网上的其他一些示例,但我的似乎由于某种原因不起作用,或者可能是我做的不对,当我在视图中打印表单时,我得到以下内容,它转到 else 语句,所以我的表格没有得到保存

<input id="id_product" type="text" name="product" value="aassddf" maxlength="250" />
FAIL

我的模型.py

from django.db import models
from django.forms import ModelForm

class Category(models.Model):
    name = models.CharField(max_length=250)

    def __unicode__(self):
        return self.name

class Product(models.Model):
    category = models.ForeignKey(Category)
    product = models.CharField(max_length=250)
    quantity = models.IntegerField(default=0)
    price = models.FloatField(default=0.0)

    def __unicode__(self):
        return self.product

class ProductForm(ModelForm):
    class Meta:
        model = Product

我的观点.py

from models import *
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect

def index(request):
    ...
    ...

def add_product(request):
    if request.method == 'POST':
        form = ProductForm(request.POST)
        print form['product']
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('/product')
        else:
            print 'FAIL'
    return HttpResponseRedirect('/product')

我的html

<form method="post" action="add_product/">
        {% csrf_token %}
        <label for="category">Category</label>
        <select name="category" id="category">
        {% for category in category_list %}
          <option> {{ category.name }} </option>
        {% endfor %}
        </select>

        <label for="product">Product</label>
        <input type="text" name="product" id="product">

        <label for="quantity">Quantitiy</label>
        <input type="text" name="quantity" id="quantity">

        <label for="price">Price</label>
        <input type="text" name="price" id="price">

        <input type="submit" value="Add New product" id="create">
    </form>

有没有更好的方法可以使用 ModelForms 保存数据?在此先感谢您的帮助。

4

3 回答 3

3

您应该阅读文档。如果表单无效,它将有与之相关的一整套错误,这将告诉您确切的原因。但你只是把它扔掉,然后重定向到/product. 文档准确地显示了如何重新显示带有错误的表单。

此外,您不应该直接在模板中编写 HTML 表单字段标签:使用视图中的表单对象 -{{ form.product }}等 - 因为这些将在重新显示时重新填充适当的值。

于 2012-10-03T12:11:45.780 回答
2

感谢 Daniel Roseman 和 Anuj Gupta,我想我终于重新编写了我的代码,让它以标准方式工作,以便生成 html 表单并验证错误。

因此,对于其他试图在这里使用 django 表单的人来说,这是我处理的代码。

我的model.py与我在问题上发布的几乎相同,但我删除了

class ProductForm(ModelForm):
    class Meta:
        model = Product

我创建了一个新的form.py这里是代码-

from django import forms
from models import Category

class ProductForm(forms.Form):
    # Put all my Categories into a select option
    category = forms.ModelChoiceField(queryset=Category.objects.all())
    product = forms.CharField()
    quantity = forms.IntegerField()
    price = forms.FloatField()  

我的views.py改变了很多变化 -

def add_product(request):
    success = False

    if request.method == "POST":        
        product_form = ProductForm(request.POST)

        if product_form.is_valid():             
            success = True

            category = Category.objects.get(name=product_form.cleaned_data['category'])
            product = product_form.cleaned_data['product']
            quantity = product_form.cleaned_data['quantity']
            price = product_form.cleaned_data['price']

            new_product = Product(category = category, product = product, quantity = quantity, price = price )
            new_product.save()

            new_product_form = ProductForm()

            ctx2 = {'success':success, 'product_form':new_product_form}
            return render_to_response('product/add_product.html', ctx2 , context_instance=RequestContext(request))
    else:
        product_form = ProductForm()
    ctx = {'product_form':product_form}
    return render_to_response('product/add_product.html', ctx , context_instance=RequestContext(request))

最后在我的html 页面中,我使用{{ product_form.as_p }}它动态创建表单

{% if success %}
    <h3> product added successfully </h3>
{% endif %}         
<form method="post" action=".">
    {% csrf_token %}

    {{ product_form.as_p }}

    <input type="submit" value="Add New product" id="create">
    <input type="reset" value="reset" id="reset">   
</form>

这可能不是完美的解决方案,但对于像我这样的初学者来说,这听起来不错,有时您在阅读文档时会迷路,哈哈,希望它对某人有所帮助。

干杯

于 2012-10-04T09:40:31.117 回答
1

尝试:

<form method="post" action="add_product/">
    {% csrf_token %}
    {{ form.as_p }}
</form>

在您的模板中,而不是手动编码表单的输入标签。此快捷方式将为您生成表单 html,以及打印验证错误。

确保在以下情况下将form对象返回到模板:

  1. 没有request.POST(表单还没有提交)
  2. form.is_valid() 失败(表单有验证错误)

当然,这只是为了让您入门。你真的应该阅读文档

于 2012-10-03T12:57:56.243 回答