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>
其他文件和上面一樣,啓動後效果
保存後->