这个示例比较复杂,需要使用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函数来渲染,这个函数从数据库取得内容,然后渲染出来。