1. 表单
表单有两种:Form和ModelForm
Form是普通的表单,需要我们自己定义一些字段,跟model无关,跟前端有关
ModelForm是跟model有关联的,跟前端也有关,利用后端对model的定义,会对前端的数据进行校验
2.示例
在first_project/personal_info路径下,新建forms.py文件(这是约定俗成的)
a.Form实现
# first_project/personal_info/views.py from django.http import HttpResponseRedirect from django.shortcuts import render # Create your views here. from django.urls import reverse from django.views import View from django.views.generic import ListView from personal_info.forms import PersionCreateForm from personal_info.models import Person class PersonList(ListView): model = Person template_name = 'personal_info/person_list.html' # 会直接上templates目录下找 def get_context_data(self, *, object_list=None, **kwargs): context = super().get_context_data(object_list=object_list, **kwargs) # 先把父类的context拿到 context.update({'list': [1.23, 2.34, 3.45]}) return context class PersonCreate(View): # http请求的get方法会调用的函数 def get(self, request, *args, **kwargs): return render(request, 'personal_info/person_create.html') def post(self, request, *args, **kwargs): data = request.POST form = PersionCreateForm(data=data) print(form.is_valid()) if form.is_valid(): # 保存数据 person = Person( # cleaned_data是form中有效的数据存储地 name=form.cleaned_data['name'], age=form.cleaned_data['age'], gender=form.cleaned_data['gender'], address=form.cleaned_data['address'], id_card=form.cleaned_data['id_card'], temperature=form.cleaned_data['temperature'], ) person.save() else: raise Exception # 跳转,因为前后端不分离的页面,在提交后是一定会跳转的 return HttpResponseRedirect(reverse('personal_info:person_list'))
# first_peoject/personal_info/urls.py from django.urls import path from personal_info import views app_name = 'personal_info' urlpatterns = [ # name值就是用来html中请求的url,会进行拼接,例如:personal_info:person_list path('', views.PersonList.as_view(), name="person_list"), path('create/', views.PersonCreate.as_view(), name="person_create"), ]
# first_project/personal_info/models.py from django.db import models # Create your models here. from django.db import models class Person(models.Model): # 继承Model GENDER_CHOICES = ( (1, '男'), (0, '女'), ) name = models.CharField(max_length=32) # 定义VARCHAR类型字段,max_length是必须的 age = models.IntegerField() # 定义整形字段 gender = models.BooleanField(choices=GENDER_CHOICES) # 定义布尔类型变量,可选择的 id_card = models.CharField(max_length=18) address = models.CharField(max_length=256) temperature = models.FloatField() # 定义浮点型字段 class Meta: # model中的配置中心 permissions = () # 将数据库权限设置为空
# first_project/personal_info/forms.py from django import forms class PersionCreateForm(forms.Form): # 这些跟models中的定义类似 name = forms.CharField() age = forms.IntegerField() gender = forms.BooleanField() id_card = forms.CharField(max_length=18) address = forms.CharField(max_length=256) temperature = forms.FloatField()
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登记人员信息</title> </head> <body> <!-- personal_info:person_create 必须要有person_create这个url 效果是请求该url会跳转到这--> <form action="{% url 'personal_info:person_create' %}" method="post"> {% csrf_token %} <!-- name中的值是后端form定义的字段名字 --> <p><label>姓名:<input type="text", name="name"></label></p> <p><label>年龄:<input type="number", name="age"></label></p> <p><label>姓别:<select name="gender"> <option value="1">男</option> <option value="0">女</option> </select></label></p> <p><label>地址:<input type="text", name="address"></label></p> <p><label>身份证:<input type="text", name="id_card"></label></p> <!-- step是上线点击 --> <p><label>体温:<input type="number", name="temperature" step="0.1"></label></p> <p><button type="submit">保存</button></p> </form> </body> </html>
{% load mytags %} <!-- 导入自定义tag --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>疫情人员登记表</title> </head> <body> <table class="table"> <thead> <tr> <th scope="col">ID</th> <th scope="col">名字</th> <th scope="col">年龄</th> <th scope="col">性别</th> <th scope="col">疑似</th> </tr> </thead> <tbody> {{ list|add_filter }} <!-- 调用自定义filter --> {% add_tag list %} <!-- 调用自定义tag --> <!-- 默认是object_list 模板语言for循环语法 --> {% for item in object_list %} <tr> <td>{{ item.id }}</td> <td>{{ item.name }}</td> <td>{{ item.age }}</td> <!-- 不加get_display会显示数字 --> <td>{{ item.gender|yesno:"男,女"}}</td> <td>{% if item.temperature > 37 %}是{% else %}否{% endif %}</td> </tr> {% empty %} <tr> <!-- 意思是将5列合并成1列 --> <td colspan="5">暂无数据</td> </tr> {% endfor %} </tbody> </table> <!-- 这个地方跳转到 personal_info:person_create url --> <p><a href="{% url 'personal_info:person_create' %}">登记</a></p> </body> </html>
启动后的效果
点击登记-> 登记完后会跳转到第一个页面,并显示添加的数据,但我这
里获取性别有问题,没找到原因
b.ModelForm
⚠️使用ModelForm,view要继承CreateView
# first_project/personal_info/views.py from django.http import HttpResponseRedirect from django.shortcuts import render # Create your views here. from django.urls import reverse, reverse_lazy from django.views import View from django.views.generic import ListView, CreateView from personal_info.forms import PersonCreateForm from personal_info.models import Person class PersonList(ListView): model = Person template_name = 'personal_info/person_list.html' # 会直接上templates目录下找 def get_context_data(self, *, object_list=None, **kwargs): context = super().get_context_data(object_list=object_list, **kwargs) # 先把父类的context拿到 context.update({'list': [1.23, 2.34, 3.45]}) return context class PersonCreate(CreateView):# 注意这里改成了CreateView # 需要定义以下四个变量 form_class = PersonCreateForm model = Person template_name = 'personal_info/person_create.html' success_url = reverse_lazy('personal_info:person_list')
# first_project/personal_info/forms.py from django import forms from personal_info.models import Person class PersonCreateForm(forms.ModelForm): class Meta: # 配置中心,前端的东西都可以在这里修改,比如css,需要的时候再查一下就可以 model = Person # 把model导进来 fields = '__all__' # 代表所有字段,也可以挨个写一下 widgets = { 'name':forms.TextInput(attrs={'id':'name_id'}) # 可以开发模式打开网页,找到name那行,看到新加了id的字段 } labels = { 'name':'名字' # 可以看到页面中的原本英文'name'变成了'名字' }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登记人员信息</title> </head> <body> <form action="{% url 'personal_info:person_create' %}" method="post"> {% csrf_token %} {{ form.as_p }} <!-- as_p会按列展示 --> <p><button type="submit">保存</button></p> </form> </body> </html>
其他文件和上面一样,启动后效果
保存后->