Django:将表单保存到数据库

3 投票
2 回答
15157 浏览
提问于 2025-04-17 14:28

我有一个这样的模型:

class Recipe(models.Model):
        title = models.CharField(max_length=100)
        ingredients = models.TextField(max_length=200,help_text="Put the ingredients required for the recepies here !")
        instructions = models.TextField(max_length=500)

        posted_on = models.DateTimeField('Posted On')

        def __unicode__(self):
                return self.title

现在我想做的是,我有一个叫做 add.html 的前端页面,上面有一个表单,内容像这样:

<!DOCTYPE html>


<head><title>New Recipe</title></head>
<body>
<h1>Add A new Recipe Here</h1>

<form action="/recipes/add/" method="post">
{% csrf_token  %}

<label>ID<label>
<input type="number" name="id"></input><br />

<label>Title </label>
<input type ="text" name="title"><br />

<label>Ingredients</label>
<input type="text" name="ingredients" />
<br />

<label>Instructions </label>
<input type="text" name="instructions" />
...

这是我用 ModelForm 保存表单的方式:

def add(request):
        if request.method == 'POST':
                form = RecipeForm(request.POST)
                if form.is_valid():

                        form.save()
                        #redirect
                        return HttpResponse("Thank you")
                else:
                        return HttpResponse("Form Not Valid")
        else:
                form = RecipeForm()

                context = Context({'form':form,})
                context.update(csrf(request))
                template = loader.get_template('myApp/add.html')
                return HttpResponse(template.render(context))

每次运行这个代码时,我总是得到 "form Invalid" 的错误信息。现在我的问题是,add.html 这个 HTML 表单是否需要和我的模型 Recipe 完全对应?
如果是的话,那么:

  1. 我该如何在 HTML 表单中添加对应的 types(比如 posted_on)?
  2. 我该如何处理 syncdb 隐式创建的 id
  3. 有没有其他的解决办法?

我刚开始学习 Django。

2 个回答

2

models.py

class Recipe(models.Model):
    title = models.CharField(max_length=100)
    ingredients = models.TextField(max_length=200,help_text="Put the ingredients required for the recepies here !")
    instructions = models.TextField(max_length=500)

    posted_on = models.DateTimeField(auto_add_now=True)

    def __unicode__(self):
            return self.title

这个文件通常用来定义你的数据模型,也就是你要存储的数据结构。在这里,你可以告诉程序你需要哪些数据,比如用户的信息、文章的内容等等。简单来说,就是告诉程序你要管理什么样的数据。

page.html

<!DOCTYPE html>

<head><title>New Recipe</title></head>
<body>
<h1>Add A new Recipe Here</h1>

<form action="/recipes/add/" method="post">
{% csrf_token  %}
     {% form.as_p %}
     <input type="submit" value="submit">
</form>
</body>
</html>

这个文件是用来设计网页的外观和布局的。它包含了你希望用户在浏览器中看到的内容,比如文字、图片和按钮等。可以把它想象成网页的“画布”,你可以在上面自由地安排各种元素,让网页看起来更美观。

views.py

from django.contrib import messages
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.shortcuts import render

def add(request):
    if request.method == 'POST':
            form = RecipeForm(request.POST)
            if form.is_valid():
                form.save()
                    return HttpResponseRedirect(reverse('app_name:url'))
            else:
                messages.error(request, "Error")
    return render(request, 'myApp/add.html', {'form': RecipeForm()})

这个文件负责处理用户的请求和响应。简单来说,当用户访问你的网页时,views.py会决定显示什么内容。它就像一个指挥家,协调不同的部分,让整个程序顺利运行。通过这个文件,你可以控制用户看到的页面和数据。

4

1) 把 posted_on 改成自动添加发布日期。

posted_on = models.DateTimeField(auto_now_add=True)

2) Django 会帮你自动生成主键 ID。

3) 为什么不使用 ModelForm 呢? 文档链接

class RecipeForm(ModelForm):
    class Meta:
        model = Recipe

你可以在 fields 中使用 excludeinclude,这样可以确保你的表单只包含你想要的 Recipe 字段。

撰写回答