代码改变世界

112-使用post的方式传值(使用form类,定向到其他页面)

2019-08-25 16:50  lzhshn  阅读(834)  评论(0编辑  收藏  举报

这个示例比较复杂,需要使用2个views函数,2个模板页面。

从103篇开始,我们已经学会了用model和form来呈现,组织即存储数据,然后通过在admin注册某个model,即可方便地利用后台增删数据。

假设我们来处理一个来宾事件,每个来宾需要写上自己的名称,并自定义头衔,然后提交。最后我们能看到所有来宾的签到。

 

1、定义模型

from django.db import models


# 定义来宾模型,每个来宾有两个属性:姓名,头衔
class GuestModel(models.Model):
    guest_name = models.CharField(max_length=32, default='匿名')
    guest_title = models.CharField(max_length=32, default='来宾')

    def __str__(self):
        return self.guest_name

    class Meta:
        ordering = ['guest_name']

来宾模型有2个属性:名称,头衔,分别都配置有默认值;

指定用来宾的名称:guest_name指代来宾;

class Meta部分表示对来宾模型指定排序,默认总是按来宾名称:guest_name进行排序。

 

2、定义表单

from django import forms
from .models import CnbTitle
from .models import GuestModel


# 新建一个form类,用来让来宾签名。来宾需要留下自己的名字,并且自定义头衔
class GuestForm(forms.ModelForm):
    class Meta:
        model = GuestModel
        fields = ['guest_name', 'guest_title']
        labels = {'guest_name': '来宾名称', 'guest_title': '来宾头衔'}

 (1)告诉表单对应GuestModel模型

(2)显示和录入两个属性:guest_name,guest_title

(3)在两个属性前添加标签

 

3、显示所有来宾签到的页面

增加新的模型之后,使用:

python3 manage.py makemigrations
python3 manage.py migrate
即可将它们添加到数据库;
然后在admin.py里注册这个模式:admin.site.register(GuestModel)

这样,我们已经可以在后台录入来宾相关数据:

现在我们用views函数和templates模板将他们显示出来:

views函数:

from django.shortcuts import render
from django.shortcuts import HttpResponse
from django.shortcuts import HttpResponseRedirect
from django.shortcuts import reverse
from .models import CnbTitle, GuestModel
from .forms import CnbTitleForm, GuestForm


# 定义了模型和表格,并在admin注册后,即可在后台录入数据,使用views函数可以处理并显示这些数据
def all_guest(request):
    allguest = GuestModel.objects.all()
    context = {'allguest': allguest}
    return render(request, 'all_guest.html', context)

 

templates页面:

其中{% empty %}用来表示当for循环里什么都没有时要显示的内容。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>All Guest</title>
</head>
<body>
    <h3>来宾签到薄:</h3>
    {% for guest in allguest %}
        <p>{{guest.guest_name}}-{{guest.guest_title}}</p>
    {% empty %}
        <p>暂无来宾录入!</p>
    {% endfor %}
</body>
</html>

 

4、实际来宾签到簿页面:

 

5、不依赖后台,提供一个页面让用户签到

views函数:

from django.shortcuts import render
from django.shortcuts import HttpResponse
from django.shortcuts import HttpResponseRedirect
from django.shortcuts import reverse
from .models import CnbTitle, GuestModel
from .forms import CnbTitleForm, GuestForm


# 使用form类,并且追加到本页面的post传值示例
def middle_post(request):
    if request.method == 'POST':
        form_result = GuestForm(request.POST)
        if form_result.is_valid():
            form_result.save()
            return HttpResponseRedirect(reverse(all_guest))
    else:
        form = GuestForm
        context = {'form': form}
        return render(request, 'middle_post.html', context)

 这里对request.method进行判断,如果为POST:

将从表格提交中获得的数据保存到form_result,然后判断其合法性,最后存到数据库,最后重定向到test_urls.py里name='all_guest'的链接,当重定向到这里后,实际上会再运行一次all_guest函数,通过重新载入数据库,会看到刚才提交的内容【对这种方式的效率存疑】;

如果不为POST:则渲染页面,这个页面能让用户自己签到。

 

 templates页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Middle Post</title>
</head>
<body>
    <form action="" method="post">
        {% csrf_token %}
        {{form.as_p}}
        <input type="submit" value="提交" />
    </form>
</body>
</html>

 注意:

(1)action仍然没有赋值

(2)使用{{form.as_p}}能让模板自动渲染表格,每行类似一个p标签

 

 6、总结:

需求:点击提交后,在另外一个页面显示提交结果。

实现:

由渲染页面的那个views函数来响应提交操作,这个函数主要做2件事情:将表格提交来的数据存入数据库,跳转到一个新页面。这个函数实际上完全没有对新页面进行任何设置;

新的页面由另一个views函数来渲染,这个函数从数据库取得内容,然后渲染出来。