目錄css
choice參數
用戶性別
用戶學歷
用戶工做狀態
客戶來源
...html
choices = ( (1,'male'), (2,'female'), (3,'others') ) gender = models.IntegerField(choices=choices) """ 1.若是我存的是上面元組中數字會怎麼樣 2.若是我存的數字不在元組範圍內又會怎樣 1.數字沒有對應關係 是能夠存的 """
from app01 import models user_obj = models.Userinfo.objects.filter(pk=4).first() print(user_obj.username) print(user_obj.gender) # 針對choices字段 若是你想要獲取數字所對應的中文 你不能直接點字段 # 固定句式 數據對象.get_字段名_display() 當沒有對應關係的時候 該句式獲取到的仍是數字 print(user_obj.get_gender_display())
實例1前端
record_choices = (('checked', "已簽到"), ('vacate', "請假"), ('late', "遲到"), ('noshow', "缺勤"), ('leave_early', "早退"), ) record = models.CharField("上課紀錄", choices=record_choices, default="checked",
實例1python
score_choices = ((100, 'A+'), (90, 'A'), (85, 'B+'), (80, 'B'), (70, 'B-'), (60, 'C+'), (50, 'C'), (40, 'C-'), (0, ' D'), (-1, 'N/A'), (-100, 'COPY'), (-1000, 'FAIL'), ) score = models.IntegerField("本節成績", choices=score_choices, default=-1)
django號稱是MTV框架,其實他仍是MVC框架
MTV:
M:models ,模型,就是數據模型,負責數據的存取;
T: templates ,模板,負責頁面的展現邏輯;
V: views ,視圖函數,負責業務邏輯的處理;
MVC:
M:models, 模型,就是數據模型,負責數據的存取;
V: views, 視圖,負責頁面的展現邏輯;
C: contronner(路由匹配), 控制器,負責業務邏輯的處理;jquery
注: 核心目的就是爲了解耦,提升開發效率ajax
AJAX(Asynchronous Javascript And XML)翻譯成中文就是「異步的Javascript和XML」。即便用Javascript語言與服務器進行異步交互,傳輸的數據爲XML(固然,傳輸的數據不僅是XML)。(我的經驗Asyn開頭,基本都是異步相關)數據庫
AJAX 不是新的編程語言,而是一種使用現有標準的新方法。django
AJAX 最大的優勢是在不從新加載整個頁面的狀況下,能夠與服務器交換數據並更新部分網頁內容。(這一特色給用戶的感覺是在不知不覺中完成請求和響應過程)編程
AJAX 不須要任何瀏覽器插件,但須要用戶容許JavaScript在瀏覽器上執行。json
$.ajax({ url:'', # 指定朝哪一個後端地址發送請求 不寫默認朝當前地址提交 type:'post', # 指定提交方式 data:{'username':'jason','password':'123'}, success:function(data){ # data指代的就是後端返回的異步提交的結果 # 異步回調機制邏輯處理代碼 } })
同步:提交任務以後 原地等待任務的返回結果 期間不幹任何事兒
異步:提交任務以後 不肯地等待 直接執行下一行代碼 任務的返回經過回調機制
程序運行的三狀態圖
一個頁面 不是總體刷新 而是頁面的某個地方局部刷新
Ajax是一門js的技術,基於原生js開發實現的,可是原生的js寫代碼過於繁瑣
只學習如何使用jQuery實現ajax
基本語法結構:
$.ajax({ url:'', # 指定抄那個後端地址發送請求,不寫默認朝當前地址提交 type:'post', # 指定提交方式 data: {'username':'json', 'password': '123'} success:function(data){ # data指代的是後端返回的異步提交的結果 # 異步回調機制邏輯代碼處理 } })
JSON 具備自我描述性,更易理解
JSON 使用 JavaScript 語法來描述數據對象,可是 JSON 仍然獨立於語言和平臺。JSON 解析器和 JSON 庫支持許多不一樣的編程語言。
合格的json對象(json只認雙引的字符串格式):
["one", "two", "three"] { "one": 1, "two": 2, "three": 3 } {"names": ["張三", "李四"] } [ { "name": "張三"}, {"name": "李四"} ]
不合格的json對象:
{ name: "張三", 'age': 32 } // 屬性名必須使用雙引號 [32, 64, 128, 0xFFF] // 不能使用十六進制值 { "name": "張三", "age": undefined } // 不能使用undefined { "name": "張三", "birthday": new Date('Fri, 26 Aug 2011 07:13:10 GMT'), "getName": function() {return this.name;} // 不能使用函數和日期對象 }
實例:
1.展現一個前端頁面 頁面上有三個輸入框 前兩個框輸入數字 點擊按鈕朝後端發請求
頁面不刷新的狀況下 完成數字的加法運算
<input type="text" id="t1"> + <input type="text" id="t2"> = <input type="text" id="t3"> <p> <button id="b1">計算</button> </p> $('#b1').on('click',function () { // 朝後端提交post數據 $.ajax({ // 1.到底朝後端哪一個地址發數據 url:'', // 專門用來控制朝後端提交數據的地址 不寫默認就是朝當前地址提交 // 2.到底發送什麼請求 type:'post', // 專門制定ajax發送的請求方式 // 3.發送的數據究竟是什麼 data:{'t1':$('#t1').val(),'t2':$('#t2').val()}, // 4.異步提交的任務 須要經過回調函數來處理 success:function (data) { // data形參指代的就是異步提交的返回結果 // 經過DOM操做將內容 渲染到標籤內容上 $('#t3').val(data) } }) })
from django.shortcuts import render,HttpResponse def index(request): print(request.is_ajax()) # 判斷當前請求是不是ajax請求 if request.is_ajax(): if request.method == 'POST': # print(request.POST) t1 = request.POST.get('t1') t2 = request.POST.get('t2') res = int(t1) + int(t2) return HttpResponse(res)
contentType先後端傳輸數據編碼格式
form表單 默認的提交數據的編碼格式是urlencoded urlencoded username=admin&password=123這種就是符合urlencoded數據格式 django後端針對username=admin&password=123的urlencoded數據格式會自動解析 將結果打包給request.POST 用戶只須要從request.POST便可獲取對應信息 formdata django後端針對formdata格式類型數據 也會自動解析可是不會方法request.POST中而是給你放到了request.FILES中 # form表單傳輸文件的時候 編碼格式就必須有默認的改成formdata ajax ajax默認的提交數據的編碼格式也是urlencoded username=jason&password=123
總結:django後端針對不一樣的編碼格式數據 會有不一樣的處理機制以及不一樣的獲取該數據的方法
先後端在作數據交互的時候 必定必定要代表你所發的的數據究竟是什麼格式
前段後交互 你不能騙人家
你的數據時什麼格式 你就應該準確無誤告訴別人是什麼格式
django後端針對json格式的數據 不會自動幫你解析 會直接原封不動的給你放到request.body中
你能夠手動處理 獲取數據
1.將bytes類型轉成json格式字符串
2.利用json模塊json.loads反序列化出來
json_bytes = request.body
json_str = str(json_bytes,encoding='utf-8')
json_dict = json.loads(json_str)
注意點: 先後端交互數據的時候 必定要作到數據個編碼格式的一致性,
1. 指定contentType參數
contentType:'application/json',
2. 要將你發送的數據 確保是json格式的 data:JSON.stringify({'username':'jason','password':'123'})
<form action="" method="post" enctype=""> # application/x-www-form-urlencoded 發普通鍵值, multipart/form-data 發文件,向普通兼容,反之不行。 <input type="text" name="username"> <input type="password" name="password"> <input type="file" name="myfile"> <input type="submit"> </form>
須要利用內置對象 Formdata 該對象既能夠傳普通的鍵值 也能夠傳文件 # 獲取input獲取用戶上傳文件的文件的內容 // 1.先經過jquery查找到該標籤 // 2.將jquery對象轉換成原生的js對象 // 3.利用原生js對象的方法 直接獲取文件內容 $('#t3')[0].files[0]
$('#b1').click(function () {
// 1.先生成一個formdata對象
var myFormData = new FormData();
// 2.朝對象中添加普通的鍵值
myFormData.append('username',$("#t1").val());
myFormData.append('password',$("#t2").val());
// 3.朝對象中添加文件數據
// 1.先經過jquery查找到該標籤
// 2.將jquery對象轉換成原生的js對象
// 3.利用原生js對象的方法 直接獲取文件內容
myFormData.append('myfile',$('#t3')[0].files[0]);
$.ajax({
url:'',
type:'post',
data:myFormData, // 直接丟對象
// ajax傳文件 必定要指定兩個關鍵性的參數 contentType:false, // 不用任何編碼 由於formdata對象自帶編碼 django可以識別該對象 processData:false, // 告訴瀏覽器不要處理個人數據 直接發就行 success:function (data) { alert(data) } }) })
「」「
ajax傳文件須要注意的事項
1.利用formdata對象 可以簡單的快速傳輸數據 (普通鍵值 + 文件)
2.有幾個參數
data:formdata對象
contentType:false
processData:false
」「」
自動把數據序列化
1.將用戶表的數據 查詢出來 返回給前端 給前端的是一個大字典 字典裏面的數據的一個個的字段 from django.core import serializers def ser(request): user_queryset = models.Userinfo.objects.all() # [{},{},{},{}] # user_list = [] # for user_obj in user_queryset: # user_list.append({ # 'username':user_obj.username, # 'password':user_obj.password, # 'gender':user_obj.get_gender_display(), # }) res = serializers.serialize('json',user_queryset) print(res) return render(request,'ser.html',locals())
ajax + sweetalert $("#b55").click(function () { swal({ title: "你肯定要刪除嗎?", text: "刪除可就找不回來了哦!", type: "warning", showCancelButton: true, // 是否顯示取消按鈕 confirmButtonClass: "btn-danger", // 確認按鈕的樣式類 confirmButtonText: "刪除", // 確認按鈕文本 cancelButtonText: "取消", // 取消按鈕文本 closeOnConfirm: false, // 點擊確認按鈕不關閉彈框 showLoaderOnConfirm: true // 顯示正在刪除的動畫效果 }, function () { var deleteId = 2; $.ajax({ url: "/delete_book/", type: "post", data: {"id": deleteId}, success: function (data) { if (data.code === 0) { swal("刪除成功!", "你能夠準備跑路了!", "success"); } else { swal("刪除失敗", "你能夠再嘗試一下!", "error") } } }) }); })
回顧: 列表添加元素的方式:
append : # 尾部追加
extend : # 合併
insert : #索引
關鍵詞: bulk_create
實例:新建Django,app
urls.py
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^index/', views.index), # 批量導入 ]
models.py
from django.db import models # Create your models here. class Book(models.Model): title = models.CharField(max_length=32)
views.py
from django.shortcuts import render from app01 import models # Create your views here. # 批量插入兩種方法 def index(request): # 1.往書籍表中插入數據 1000 for i in range(1000): # 這種插入方式 效率極低 models.Book.objects.create(title='第%s本書'%i) book_list = [] book_queryest = models.Book.objects.all() return render(request,'index.html', locals()) # 1.往書籍表中插入數據 100000 for i in range(100000): # 時間仍是很短 二者差距很大 book_list.append(models.Book(title='第%s本書'%i)) models.Book.objects.bulk_create(book_list) # 批量插入數據 # 2.將剛剛插入的數據查詢出來展現到前端 book_queryset = models.Book.objects.all() return render(request,'index.html',locals())
封裝:項目下新建文件夾utils,在該文件夾下mypage.py文件,將下列代碼複製進去
class Pagination(object): def __init__(self, current_page, all_count, per_page_num=10, pager_count=11): """ 封裝分頁相關數據 :param current_page: 當前頁 :param all_count: 數據庫中的數據總條數 :param per_page_num: 每頁顯示的數據條數 :param pager_count: 最多顯示的頁碼個數 用法: queryset = model.objects.all() page_obj = Pagination(current_page,all_count) page_data = queryset[page_obj.start:page_obj.end] 獲取數據用page_data而再也不使用原始的queryset 獲取前端分頁樣式用page_obj.page_html """ try: current_page = int(current_page) except Exception as e: current_page = 1 if current_page < 1: current_page = 1 self.current_page = current_page self.all_count = all_count self.per_page_num = per_page_num # 總頁碼 all_pager, tmp = divmod(all_count, per_page_num) if tmp: all_pager += 1 self.all_pager = all_pager self.pager_count = pager_count self.pager_count_half = int((pager_count - 1) / 2) @property def start(self): return (self.current_page - 1) * self.per_page_num @property def end(self): return self.current_page * self.per_page_num def page_html(self): # 若是總頁碼 < 11個: if self.all_pager <= self.pager_count: pager_start = 1 pager_end = self.all_pager + 1 # 總頁碼 > 11 else: # 當前頁若是<=頁面上最多顯示11/2個頁碼 if self.current_page <= self.pager_count_half: pager_start = 1 pager_end = self.pager_count + 1 # 當前頁大於5 else: # 頁碼翻到最後 if (self.current_page + self.pager_count_half) > self.all_pager: pager_end = self.all_pager + 1 pager_start = self.all_pager - self.pager_count + 1 else: pager_start = self.current_page - self.pager_count_half pager_end = self.current_page + self.pager_count_half + 1 page_html_list = [] # 添加前面的nav和ul標籤 page_html_list.append(''' <nav aria-label='Page navigation>' <ul class='pagination'> ''') first_page = '<li><a href="?page=%s">首頁</a></li>' % (1) page_html_list.append(first_page) if self.current_page <= 1: prev_page = '<li class="disabled"><a href="#">上一頁</a></li>' else: prev_page = '<li><a href="?page=%s">上一頁</a></li>' % (self.current_page - 1,) page_html_list.append(prev_page) for i in range(pager_start, pager_end): if i == self.current_page: temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i,) else: temp = '<li><a href="?page=%s">%s</a></li>' % (i, i,) page_html_list.append(temp) if self.current_page >= self.all_pager: next_page = '<li class="disabled"><a href="#">下一頁</a></li>' else: next_page = '<li><a href="?page=%s">下一頁</a></li>' % (self.current_page + 1,) page_html_list.append(next_page) last_page = '<li><a href="?page=%s">尾頁</a></li>' % (self.all_pager,) page_html_list.append(last_page) # 尾部添加標籤 page_html_list.append(''' </nav> </ul> ''') return ''.join(page_html_list)
前端文件:
index.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.3.1/js/bootstrap.min.js"></script> </head> <body> {% for book_obj in book_queryest %} <p>{{ book_obj.title }}</p> {% endfor %} <nav aria-label="Page navigation"> <ul class="pagination"> <li> <a href="#" aria-label="Previous"> <span aria-hidden="true">«</span> </a> </li> {{ page_html|safe }} {# <li><a href="?page=1">1</a></li>#} {# <li><a href="?page=2">2</a></li>#} {# <li><a href="?page=3">3</a></li>#} {# <li><a href="?page=4">4</a></li>#} {# <li><a href="?page=5">5</a></li>#} <li> <a href="#" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> </ul> </nav> </body> </html>
login.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.3.1/js/bootstrap.min.js"></script> </head> <body> {% for book_obj in page_queryset %} <p>{{ book_obj.title }}</p> {% endfor %} {{ page_obj.page_html|safe }} </body> </html>
views.py
from django.shortcuts import render,HttpResponse,redirect from app01 import models # Create your views here. from django.core.exceptions import ValidationError def index(request): # 1.往書籍表中插入數據 1000 # for i in range(1000): # 這種插入方式 效率極低 # models.Book.objects.create(title='第%s本書'%i) book_list = [] for i in range(100000): book_list.append(models.Book(title='第%s本書'%i)) models.Book.objects.bulk_create(book_list) # 批量插入數據 # 2.將剛剛插入的數據查詢出來展現到前端 # # 1.獲取用戶想要訪問的頁碼數 current_page = request.GET.get('page',1) # 若是沒有page參數 默認就展現第一頁 # # 轉成整型 current_page = int(current_page) # # 2.每頁展現10條數據 per_page_num = 10 # # # 3.定義起始位置和終止位置 start_page = (current_page - 1) * per_page_num end_page = current_page * per_page_num # # # 4.統計數據的總條數 book_queryset = models.Book.objects.all() all_count = book_queryset.count() # # # 5.求數據到底須要多少頁才能展現完 page_num, more = divmod(all_count,per_page_num) # divmod(100,10) if more: page_num += 1 # page_num就以爲了 須要多少個頁碼 page_html = '' xxx = current_page # xxx就是用戶點擊的數字 if current_page < 6: current_page = 6 for i in range(current_page-5,current_page+6): if xxx == i: page_html += '<li class="active"><a href="?page=%s">%s</a></li>'%(i,i) else: page_html += '<li><a href="?page=%s">%s</a></li>' % (i, i) book_queryset = book_queryset[start_page:end_page] return render(request,'index.html',locals()) """ 分頁思路 per_page_num = 10 current_page start_page end_page 1 0 10 2 10 20 3 20 30 4 30 40 per_page_num = 5 current_page start_page end_page 1 0 5 2 5 10 3 10 15 4 15 20 start_page = (current_page - 1) * per_page_num end_page = current_page * per_page_num """ from app01.utils.mypage import Pagination # 使用封裝好的分頁器代碼 def login(request): book_queryset = models.Book.objects.all() current_page = request.GET.get('page',1) all_count = book_queryset.count() # 1.實例化產生對象 page_obj = Pagination(current_page=current_page,all_count=all_count) # 2.對真實數據進行切片操做 page_queryset = book_queryset[page_obj.start:page_obj.end] return render(request,'login.html',locals())
urls.py:
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^index/', views.index), url(r'^login/', views.login), ]
自定義分頁器的使用 新建一個py文件將代碼直接拷貝過去 後端 from app01.utils.mypage import Pagination # 使用封裝好的分頁器代碼 def login(request): book_queryset = models.Book.objects.all() current_page = request.GET.get('page',1) all_count = book_queryset.count() # 1.實例化產生對象 page_obj = Pagination(current_page=current_page,all_count=all_count) # 2.對真實數據進行切片操做 page_queryset = book_queryset[page_obj.start:page_obj.end] return render(request,'login.html',locals()) 前端 {% for book_obj in page_queryset %} <p>{{ book_obj.title }}</p> {% endfor %} {{ page_obj.page_html|safe }}
class Book(models.Model): ... authors = models.ManyToManyField(to='Author') class Author(models.Models): ...
class Book(models.Model): ... class Author(models.Models): ... class Book2Author(models.Model): book_id = models.ForeignKey(to='Book') author_id = models.ForeignKey(to='Author') create_time = models.DateField(auto_now_add=True) ...
手動建表 可是你會告訴orm 第三張表是你本身建的
orm只須要給我提供方便的查詢方法
第三種雖然可使用orm查詢方法
可是不支持使用
add()
set()
remove()
clear()
class Book(models.Model): ... authors = models.ManyToManyField(to='Author', through='Book2Author', through_fields=('book','author')) class Author(models.Model): ... books = models.ManyToManyField(to='Book', through='Book2Author', through_fields=('author', 'book')) class Book2Author(models.Model): book = models.ForeignKey(to='Book') author = models.ForeignKey(to='Author') create_time = models.DateField(auto_now_add=True) ... # 1.半自動 必定要加兩個額外的參數 through='Book2Author', through_fields=('book','author') # 2.後面字段的順序 由第三張表經過哪一個字段查詢單表 就把哪一個字段放前面 """ 在設計項目的時候 必定要給本身留後路 防止後續的迭代更新 """
1.註冊功能
用戶輸入的用戶名中 不能包含《書名》
若是包含了 就提示用戶 輸入的內容不符合社會主義核心價值觀
用戶輸入的密碼 不能小於三位
若是密碼少於三位 提示用戶 密碼過短了
校驗數據一般是先後端都有校驗
可是前端校驗無關緊要
後端也必需要有校驗 反正一句話 前端可有不校驗 後端必須校驗!!!
1.搭建前端頁面 >>> 渲染頁面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.3.1/js/bootstrap.min.js"></script> </head> <body> <form action="" method="post"> <p>username: <input type="text"name="userrname"> <span style="...">{{ back_dic.username }}</span>> </p> <p>password:<input type="text" name="username"> <span style="...">{{ back_dic.password }}</span> </p> <input type="submit"> </form> </body> </html>
2.獲取前端用戶提交的數據校驗 >>> 校驗數據
def reg(request): back_dic = {"username":'', "password":''} if request.method == 'POST': username = request.POST.get("username") password = request.POST.get('password') if "書名" in username: back_dic['username'] = '不符合社會主義核心價值觀' if len(password) < 3: back_dic['password'] = '密碼不能少於三位數' return request(request, 'reg.html', locals())
3.對數據的校驗的結果 展現到前端頁面給用戶查看 >>> 展現錯誤信息
因書名含敏感字換爲書名
form組件可以自動幫你完成上面的三件事
1.渲染頁面
2.校驗數據
3.展現錯誤信息
views:
class MyRegForm(forms.Field): username = forms.CharField(min_length=3, max_length=8) password = forms.CharField(min_length=3, max_length=8) email = forms.EmailField() # 是什麼數據類型就必須傳什麼數據類型
python Console:
from app01 import views # 1.給自定義的類傳一個字典 obj = views.MyRegForm({'username':'jason','password':'12','email':'123'}) # 2.判斷數據是否所有合法 obj.is_valid() # 只有數據所有符合要求才會是True Out[4]: False # 3.查看符合校驗規則的數據 obj.cleaned_data Out[5]: {'username': 'jason'} # 4.查看不符合條件的數據以及不符合的緣由是什麼 obj.errors Out[6]: { 'password': ['Ensure this value has at least 3 characters (it has 2).'], 'email': ['Enter a valid email address.'] } # 5.校驗數據的時候 默認狀況下類裏面全部的字段都必須傳值 obj = views.MyRegForm({'username':'jason','password':'123'}) obj.is_valid() Out[12]: False obj.errors Out[13]: {'email': ['This field is required.']} # 6.默認狀況下能夠多傳 可是絕對不能少傳 obj = views.MyRegForm({'username':'jason','password':'1233','email':'123@qq.com','xxx':'ooo'}) obj.is_valid() Out[15]: True
formmm.html
1.forms組件只會幫你渲染獲取用戶輸入(輸入,選擇,下拉框...)的標籤 提交按鈕須要你本身手動寫 <p>三種渲染前端頁面的方式</p> <p>第一種渲染前端頁面的方式:封裝程度過高了 標籤樣式及參數不方便調整 可擴展性差(不推薦使用) {{ form_obj.as_p }} {{ form_obj.as_ul }} </p> <p>第二種渲染頁面的方式:擴展性較高 不足之處在於 須要你手寫的代碼量比較多(不推薦使用)</p> <p> {{ form_obj.username.label }}{{ form_obj.username }} </p> <p> {{ form_obj.password.label }}{{ form_obj.password }} </p> <p> {{ form_obj.email.label }}{{ form_obj.email }} </p> <p>第三種渲染前端頁面的方式:代碼量和擴展性都很高(推薦使用)</p> {% for foo in form_obj %} <p>{{ foo.label }}{{ foo }}</p> {% endfor %} 如何展現錯誤信息 如何取消前端幫咱們作的校驗 form表單中添加一個參數便可 <form action="" method="post" novalidate> 展現錯誤信息 用對象點errors.0 <form action="" method="post" novalidate> {% for foo in form_obj %} <p> {{ foo.label }}:{{ foo }} <span style="color: red">{{ foo.errors.0 }}</span> </p> {% endfor %} <input type="submit"> </form>
views:
from django import forms class MyRegForm(forms.Form): username = forms.CharField(min_length=3,max_length=8,label='用戶名', error_messages={ 'min_length':'用戶名最短三位', 'max_length':'用戶名最長八位', 'required':'用戶名不能爲空' },initial='我是初始值',required=False ) password = forms.CharField(min_length=3,max_length=8,label='密碼',error_messages={ 'min_length':'密碼最短三位', 'max_length':'密碼最長八位', 'required':'密碼不能爲空' }) email = forms.EmailField(label='郵箱',error_messages={ 'required':'郵箱不能爲空', 'invalid':'郵箱格式不正確' },required=False)
forms組件展現錯誤
forms組件鉤子函數 針對字段 你還能夠作額外的校驗 須要經過鉤子函數 局部鉤子 # 當你須要對某一個字段數據進行額外的一些列校驗 你能夠考慮使用鉤子函數 # 針對單個字段的 使用局部鉤子 def clean_username(self): username = self.cleaned_data.get('username') if '書名' in username: # 給username字段下面提示錯誤信息 self.add_error('username','用戶名不符合社會主義核心價值觀') return username 全局鉤子 # 針對多個字段的校驗 使用全局鉤子 eg:校驗兩次密碼是否一致 def clean(self): password = self.cleaned_data.get('password') confirm_password = self.cleaned_data.get('confirm_password') if not password == confirm_password: self.add_error('confirm_password','兩次密碼不一致') return self.cleaned_data 如何改變input框的type屬性值 widget= widgets.TextInput() widget=widgets.PasswordInput() 如何讓forms組件渲染出來的input框有form-control類屬性 widget= widgets.TextInput(attrs={'class':'form-control others'}) # 若是有多個類屬性 空格隔開 widget=widgets.PasswordInput(attrs={'class':'form-control others'}) 每一個字段 還支持正則校驗 from django import forms from django.forms import Form from django.core.validators import RegexValidator class MyForm(Form): user = forms.CharField( validators=[RegexValidator(r'^[0-9]+$', '請輸入數字'), RegexValidator(r'^159[0-9]+$', '數字必須以159開頭')], )