django(7)modelform操作及验证、ajax操作普通表单数据提交、文件上传、富文本框基本使用...
生活随笔
收集整理的這篇文章主要介紹了
django(7)modelform操作及验证、ajax操作普通表单数据提交、文件上传、富文本框基本使用...
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、modelForm操作及驗證
1.獲取數據庫數據,界面展示數據并且獲取前端提交的數據,并動態顯示select框中的數據
views.py
from django.shortcuts import render,HttpResponse from app01 import modelsfrom django import forms from django.forms import fields as Ffields from django.forms import widgets as Fwidgets class UserInfoModelForm(forms.ModelForm):class Meta:#必須添加model = models.UserInfo#指定去UserInfo表里獲取數據fields = '__all__' #在界面顯示所有字段# fields = ['username','email']#只在界面顯示'username','email'字段# exclude = ['username'] #不在界面顯示'username'字段class UserInfoForm(forms.Form):username = Ffields.CharField(max_length=32)email = Ffields.EmailField()user_type = Ffields.ChoiceField(choices=models.UserType.objects.values_list('id','caption')#以'id','caption'為select框中的數據 )def __init__(self, *args, **kwargs):super(UserInfoForm,self).__init__(*args, **kwargs)self.fields['user_type'].choices = models.UserType.objects.values_list('id','caption')#加上這個init函數#后,就能將新添加到數據庫中的數據動態顯示到select框啦def index(request):if request.method == "GET":#將數據展示在界面obj = UserInfoModelForm()return render(request,'index.html',{'obj': obj})elif request.method == "POST":#獲取前端提交的數據obj = UserInfoModelForm(request.POST)if obj.is_valid():#obj.is_valid()只能為true或falseprint(obj.is_valid())print(obj.cleaned_data) #obj.cleaned_data以字典的形式展示前端提交的數據print(obj.errors.as_json())#打印錯誤信息return render(request,'index.html',{'obj': obj})index.html
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title></title> </head> <body><form action="/index/" method="POST">{% csrf_token %}{{ obj.as_p }} #以p標簽的形式展示數據<input type="submit" value="提交" /></form> </body> </html> View Code二、完整的在界面展示數據、修改數據、提交數據、跳轉到新頁面
views.py
from django.shortcuts import render,HttpResponse from app01 import modelsfrom django import forms from django.forms import fields as Ffields#給導入的fields設置別名為Ffields from django.forms import widgets as Fwidgets#給導入的widgets設置別名為Fwidgets class UserInfoModelForm(forms.ModelForm):is_rmb = Ffields.CharField(widget=Fwidgets.CheckboxInput())#自定義在界面顯示的單選框等,而且不用保存在數據庫class Meta:#class Meta里一定不要加逗號model = models.UserInfo#指定去UserInfo表里獲取數據fields = '__all__' #在界面顯示所有字段# fields = ['username','email']#只在界面顯示'username','email'字段# exclude = ['username'] #不在界面顯示'username'字段labels = {#設定輸入框的標簽名'username': '用戶名','email': '郵箱',}help_texts = {#在輸入框后面自定義幫助信息'username': '我是幫助信息'}widgets = {#自定義輸入框的屬性,即自定義html標簽的class'username': Fwidgets.Textarea(attrs={'class': 'c1'})#將輸入框設置為text文本框,并添加css:‘c1’ }error_messages = {#自定義錯誤信息提示'__all__':{#給整體設置錯誤信息,跟form中的all一樣 },'email': {#給每個字段設定錯誤信息'required': '郵箱不能為空','invalid': '郵箱格式錯誤..',}}field_classes = {#將email輸入框的格式驗證修改為必須輸入URL格式才正確# 'email': Ffields.URLField }localized_fields=('ctime',)#將數據庫時間轉化為北京時間,括號里寫需要轉化時間的字段,需要在settings里設置#timezoneclass UserInfoForm(forms.Form):username = Ffields.CharField(max_length=32)email = Ffields.EmailField()user_type = Ffields.ChoiceField(choices=models.UserType.objects.values_list('id','caption')#以'id','caption'為select框中的數據 )def __init__(self, *args, **kwargs):super(UserInfoForm,self).__init__(*args, **kwargs)self.fields['user_type'].choices = models.UserType.objects.values_list('id','caption')#加上這個init函數#后,就能將新添加到數據庫中的數據動態顯示到select框啦def index(request):#將數據展示在界面if request.method == "GET":obj = UserInfoModelForm()return render(request,'index.html',{'obj': obj})elif request.method == "POST":obj = UserInfoModelForm(request.POST)if obj.is_valid():#obj.is_valid()只能為true或falseobj.save()#自動將前端提交的數據保存在數據庫# print(obj.cleaned_data) #obj.cleaned_data以字典的形式獲取前端提交的數據# print(obj.errors.as_json())return render(request,'index.html',{'obj': obj})def user_list(request):li = models.UserInfo.objects.all().select_related('user_type')#獲取UserInfo表中的所有數據,并且跨表將與UserInfo# 關聯的user_type表中的數據也取出來,注意括號中寫UserInfo類中的關聯字段名,不可以寫多對多的字段名,否則報錯,#前端html跨表取user_type表數據:{% for row in li %} {{ row.user_type.caption }}return render(request,'user_list.html',{'li': li})def user_edit(request, nid):# 1.獲取當前id對應的用戶信息# 2.顯示用戶已經存在數據if request.method == "GET":#數據展示user_obj = models.UserInfo.objects.filter(id=nid).first()#根據nid獲取UserInfo表中的相關數據的第一條mf = UserInfoModelForm(instance=user_obj)#將mf傳到前端就可以自動生成網頁,括號中的instance參數是顯示默認值return render(request,'user_edit.html',{'mf': mf, 'nid': nid})#跳轉回本頁面,也可以跳轉到其他頁面elif request.method == 'POST':#數據修改user_obj = models.UserInfo.objects.filter(id=nid).first()mf = UserInfoModelForm(request.POST,instance=user_obj)#如果不加這句,就會自動在數據庫中新添加數據,而不是修改#已存在的數據if mf.is_valid():mf.save()#將修改的數據寫入到數據庫中else:#如果出現異常,打印錯誤信息print(mf.errors.as_json())return render(request,'user_edit.html',{'mf': mf, 'nid': nid})urls.py
url(r'^admin/', admin.site.urls),url(r'^index/', views.index),url(r'^user_list/', views.user_list),url(r'^edit-(\d+)/', views.user_edit),index.html
同上
user_list.html
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title></title> </head> <body><ul>{% for row in li %}<li>{{ row.username }} - {{ row.user_type.caption }} - <a href="/edit-{{ row.id }}/">編輯</a></li>{% endfor %}</ul> </body> </html> View Codeuser_edit.html
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title></title> </head> <body><form method="POST" action="/edit-{{ nid }}/"> #以新鏈接的形式提交數據{% csrf_token %}{{ mf.as_p }}<input type="submit" value="提交" /></form></body> </html>?三、ajax操作發送表單,并且獲取數據,頁面不刷新
1.給后臺發送普通數據
views.py
def ajax(request):return render(request, 'ajax.html')def ajax_json(request):import timeprint(request.POST)ret = {'code': True , 'data': request.POST.get('username')}import jsonreturn HttpResponse(json.dumps(ret))ajax.html
有兩種ajax提交方式:推薦用第一種
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title></title> </head> <body><input type="text"/><input type="button" value="Ajax1" onclick="Ajax1();" />第二種:ifram提交數據<form action="/ajax_json/" method="POST" target="ifm1"><iframe id="ifm1" name="ifm1" ></iframe><input type="text" name="username" /><input type="text" name="email" /><input type="submit" onclick="sumitForm();" value="Form提交"/></form><script type="text/javascript" src="/static/jquery-1.12.4.js"></script><script>第一種:ajax提交表單數據function getXHR(){var xhr = null;if(XMLHttpRequest){xhr = new XMLHttpRequest();}else{xhr = new ActiveXObject("Microsoft.XMLHTTP");}return xhr;}function Ajax1(){var xhr = getXHR();//var xhr = new XMLHttpRequest(); xhr.open('POST', '/ajax_json/',true);#括號內參數依次為:數據提交方式、提交去處、是否異步,true為異步xhr.onreadystatechange = function(){if(xhr.readyState == 4){// 接收完畢var obj = JSON.parse(xhr.responseText);console.log(obj);}};xhr.setRequestHeader('k1','v1');xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');xhr.send("name=root;pwd=123");}{# 第二種:ifram提交表單數據#}function sumitForm(){$('#ifm1').load(function(){var text = $('#ifm1').contents().find('body').text();var obj = JSON.parse(text);})}</script> </body> </html>?
ifram詳解:
<body><form action="/ajax_json/" method="POST" target="ifm1">#表單提交到/ajax_json/ target:在指定的框架中打開<iframe id="ifm1" name="ifm1" ></iframe> #加上display:none就看不到ifram框啦<input type="text" name="username" /><input type="text" name="email" /><input type="submit" onclick="sumitForm();" value="Form提交"/></form> <script> function sumitForm(){#獲取ifram框架中的數據$('#ifm1').load(function(){var text = $('#ifm1').contents().find('body').text(); #.contents():由于ifram生成的是完整的html網頁,通過contents()屬性提取出網頁內容,再找到body標簽,#再通過text方法找到后臺返回的數據var obj = JSON.parse(text); #將獲取到的后臺數據json序列化})}</script>
2.給后臺上傳文件,上傳文件有三種方式,優先使用ifram,再次使用jQuery ajax
views.py
def upload(request):return render(request,'upload.html')def upload_file(request):username = request.POST.get('username')fafafa = request.FILES.get('fafafa')import osimg_path = os.path.join('static/imgs/',fafafa.name)#生成圖片保存路徑with open(img_path,'wb') as f:for item in fafafa.chunks():#保存文件,必須用chunks() f.write(item)ret = {'code': True , 'data': img_path}#將圖片路徑返回給前端import jsonreturn HttpResponse(json.dumps(ret))?
upload.html
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title></title><style>.upload{display: inline-block;padding: 10px;background-color: brown;position: absolute;top: 0;bottom: 0;right: 0;left: 0;z-index: 90;}.file{width: 100px;height: 50px;opacity: 0;position: absolute;top: 0;bottom: 0;right: 0;left: 0;z-index: 100;}</style> </head> <body><div style="position: relative;width: 100px;height: 50px;"><input class="file" type="file" id="fafafa" name="afafaf" /><a class="upload">上傳</a></div>第一種上傳方式:原生ajax<input type="button" value="提交XHR" onclick="xhrSubmit();" />第二種上傳方式:jQuery ajax<input type="button" value="提交jQuery" onclick="jqSubmit();" /><hr/> 分隔符第三種上傳方式:ifram 最好用第三和第二種<form id="form1" action="/upload_file/" method="POST" enctype="multipart/form-data" target="ifm1"><iframe id="ifm1" name="ifm1" style="display: none;"></iframe><input type="file" name="fafafa" onchange="changeUpalod();" /><input type="submit" onclick="iframeSubmit();" value="Form提交"/></form><div id="preview"></div><script src="/static/jquery-1.12.4.js"></script><script>這一步可以不要,選中圖片后自動提交,并且生成圖片預覽function changeUpalod(){$('#ifm1').load(function(){var text = $('#ifm1').contents().find('body').text();var obj = JSON.parse(text); 獲取圖片路徑$('#preview').empty(); #將預覽圖片標簽清空var imgTag = document.createElement('img'); 生成圖片標簽imgTag.src = "/" + obj.data; 生成圖片路徑$('#preview').append(imgTag);});$('#form1').submit();}以下有三種文件提交方式,優先使用ifram,再次使用jQuery提交文件以下這一步是:jQuery提交文件function jqSubmit(){// $('#fafafa')[0]var file_obj = document.getElementById('fafafa').files[0];var fd = new FormData();fd.append('username','root');fd.append('fafafa',file_obj);$.ajax({url: '/upload_file/',type: 'POST',data: fd,processData: false, // tell jQuery not to process the data contentType: false, // tell jQuery not to set contentType success:function(arg,a1,a2){console.log(arg);console.log(a1);console.log(a2);}})}以下這一步是:原生ajax提交文件function xhrSubmit(){// $('#fafafa')[0]var file_obj = document.getElementById('fafafa').files[0];var fd = new FormData();fd.append('username','root');fd.append('fafafa',file_obj);var xhr = new XMLHttpRequest();xhr.open('POST', '/upload_file/',true);xhr.onreadystatechange = function(){if(xhr.readyState == 4){// 接收完畢var obj = JSON.parse(xhr.responseText);console.log(obj);}};xhr.send(fd);}以下這一步是:ifram提交文件,優先使用ifram提交function iframeSubmit(){$('#ifm1').load(function(){var text = $('#ifm1').contents().find('body').text();var obj = JSON.parse(text); 獲取圖片路徑$('#preview').empty(); #將預覽圖片標簽清空var imgTag = document.createElement('img'); 生成圖片標簽imgTag.src = "/" + obj.data; 生成圖片路徑$('#preview').append(imgTag);});}</script> </body> </html> View Code四、生成圖片驗證碼
check_code.py
#!/usr/bin/env python # -*- coding:utf-8 -*-import random from PIL import Image, ImageDraw, ImageFont, ImageFilter_letter_cases = "abcdefghjkmnpqrstuvwxy" # 小寫字母,去除可能干擾的i,l,o,z _upper_cases = _letter_cases.upper() # 大寫字母 _numbers = ''.join(map(str, range(3, 10))) # 數字 init_chars = ''.join((_letter_cases, _upper_cases, _numbers))def create_validate_code(size=(120, 30),chars=init_chars,img_type="GIF",mode="RGB",bg_color=(255, 255, 255),fg_color=(0, 0, 255),font_size=18,font_type="Monaco.ttf",length=4,draw_lines=True,n_line=(1, 2),draw_points=True,point_chance=2):"""@todo: 生成驗證碼圖片@param size: 圖片的大小,格式(寬,高),默認為(120, 30)@param chars: 允許的字符集合,格式字符串@param img_type: 圖片保存的格式,默認為GIF,可選的為GIF,JPEG,TIFF,PNG@param mode: 圖片模式,默認為RGB@param bg_color: 背景顏色,默認為白色@param fg_color: 前景色,驗證碼字符顏色,默認為藍色#0000FF@param font_size: 驗證碼字體大小@param font_type: 驗證碼字體,默認為 ae_AlArabiya.ttf@param length: 驗證碼字符個數@param draw_lines: 是否劃干擾線@param n_lines: 干擾線的條數范圍,格式元組,默認為(1, 2),只有draw_lines為True時有效@param draw_points: 是否畫干擾點@param point_chance: 干擾點出現的概率,大小范圍[0, 100]@return: [0]: PIL Image實例@return: [1]: 驗證碼圖片中的字符串"""width, height = size # 寬高# 創建圖形img = Image.new(mode, size, bg_color)draw = ImageDraw.Draw(img) # 創建畫筆def get_chars():"""生成給定長度的字符串,返回列表格式"""return random.sample(chars, length)def create_lines():"""繪制干擾線"""line_num = random.randint(*n_line) # 干擾線條數for i in range(line_num):# 起始點begin = (random.randint(0, size[0]), random.randint(0, size[1]))# 結束點end = (random.randint(0, size[0]), random.randint(0, size[1]))draw.line([begin, end], fill=(0, 0, 0))def create_points():"""繪制干擾點"""chance = min(100, max(0, int(point_chance))) # 大小限制在[0, 100]for w in range(width):for h in range(height):tmp = random.randint(0, 100)if tmp > 100 - chance:draw.point((w, h), fill=(0, 0, 0))def create_strs():"""繪制驗證碼字符"""c_chars = get_chars()strs = ' %s ' % ' '.join(c_chars) # 每個字符前后以空格隔開 font = ImageFont.truetype(font_type, font_size)font_width, font_height = font.getsize(strs)draw.text(((width - font_width) / 3, (height - font_height) / 3),strs, font=font, fill=fg_color)return ''.join(c_chars)if draw_lines:create_lines()if draw_points:create_points()strs = create_strs()# 圖形扭曲參數params = [1 - float(random.randint(1, 2)) / 100,0,0,0,1 - float(random.randint(1, 10)) / 100,float(random.randint(1, 2)) / 500,0.001,float(random.randint(1, 2)) / 500]img = img.transform(size, Image.PERSPECTIVE, params) # 創建扭曲 img = img.filter(ImageFilter.EDGE_ENHANCE_MORE) # 濾鏡,邊界加強(閾值更大)return img, strs View Codeviews.py
#!/usr/bin/env python # -*- coding:utf-8 -*- from io import BytesIO from django.shortcuts import HttpResponse from django.shortcuts import render from utils.check_code import create_validate_codedef check_code(request):#該函數對應login.html中的src=/check_code.html"""驗證碼:param request::return:"""# stream = BytesIO()# img, code = create_validate_code()# img.save(stream, 'PNG')# request.session['CheckCode'] = code# return HttpResponse(stream.getvalue())# data = open('static/imgs/avatar/20130809170025.png','rb').read()# return HttpResponse(data)# 1. 創建一張圖片 pip3 install Pillow# 2. 在圖片中寫入隨機字符串# obj = object()# 3. 將圖片寫入到制定文件# 4. 打開制定目錄文件,讀取內容# 5. HttpResponse(data) stream = BytesIO()#生成一個內存對象img, code = create_validate_code() #生成圖片和驗證碼img.save(stream,'PNG')#將圖片保存到內存中,格式為pngrequest.session['CheckCode'] = code #將驗證碼放到session里return HttpResponse(stream.getvalue())#stream.getvalue()將圖片從內存中取出,返回給前端def login(request):"""登陸:param request::return:"""# if request.method == "POST":# if request.session['CheckCode'].upper() == request.POST.get('check_code').upper():# pass# else:# print('驗證碼錯誤')if request.method == 'POST':code = request.POST.get('check_code')if code.upper() == request.session['CheckCode'].upper():print('驗證碼正確')else:print('驗證碼錯誤')return render(request, 'login.html')def register(request):"""注冊:param request::return:"""return render(request, 'register.html')def logout(request):"""注銷:param request::return:"""passlogin.html
<!DOCTYPE html> <html> <head lang="en"><meta charset="UTF-8"><title></title><link rel="stylesheet" href="/static/plugins/bootstrap/css/bootstrap.css"/><link rel="stylesheet" href="/static/plugins/font-awesome/css/font-awesome.css"/><link rel="stylesheet" href="/static/css/edmure.css"/><link rel="stylesheet" href="/static/css/commons.css"/><link rel="stylesheet" href="/static/css/account.css"/><style></style> </head> <body> <div class="login"><div style="font-size: 25px; font-weight: bold;text-align: center;">用戶登陸</div><form role="form" action="/login.html" method="POST">{% csrf_token %}<div class="form-group"><label for="username">用戶名</label><input type="text" class="form-control" placeholder="請輸入用戶名"></div><div class="form-group"><label for="password">密碼</label><input type="password" class="form-control" placeholder="請輸入密碼"></div><div class="form-group"><label for="password">驗證碼</label><div class="row"><div class="col-xs-7"><input type="text" class="form-control" placeholder="請輸入驗證碼" name="check_code"></div><div class="col-xs-5"><img src="/check_code.html" οnclick="changeCheckCode(this);">#綁定事件,點擊圖片生成新的驗證碼</div></div></div><div class="checkbox"><label><input type="checkbox"> 一個月內自動登陸</label><div class="right"><a href="#">忘記密碼?</a></div></div><button type="submit" class="btn btn-default">登 陸</button></form> </div><script>function changeCheckCode(ths){ths.src = ths.src + '?'; {# 通過在url后邊加問號的形式,實現點擊驗證碼圖片刷新頁面獲取新的驗證碼#} }</script> </body> </html>五、富文本框使用
http://www.cnblogs.com/wupeiqi/articles/6307554.html? ?視頻24天-17-KindEditor基本使用和文件操作
?
轉載于:https://www.cnblogs.com/wt11/p/6363866.html
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的django(7)modelform操作及验证、ajax操作普通表单数据提交、文件上传、富文本框基本使用...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 云计算学习(1-1)云计算的定义
- 下一篇: java service wrapper