1. 程式人生 > >Django子應用裏的通用類混合視圖處理

Django子應用裏的通用類混合視圖處理

decorator num quest utf tde 驗證 move 唯一性 頭部

# 子應用的views.py此文件用於編寫Web應用視圖,處理復雜的業務邏輯

#導入方法視圖模板
from django.shortcuts import render
#導包
from django.http import HttpResponse,HttpResponseRedirect,JsonResponse
#導入類視圖
from django.views import View
#從配置文件已安裝的django應用模塊導入數據庫類
from mysite.models import User
from supermarket.models import Product
#導入json
import json #導入時間模塊 import time #導入源生sql連接 from django.db import connection #導入通用類視圖裝飾器 from django.utils.decorators import method_decorator #定義一個用cookie驗證登錄的裝飾器decorator #用session驗證登錄的裝飾器只需換下變量名,在註銷功能改下即可 def cookie(func): def wrapper(request,*args,**kwargs): login = request.COOKIES.get("
username",False) if not login: return HttpResponseRedirect(/supermarket/login) return func(request,*args,**kwargs) return wrapper #定義反爬裝飾器,定義形參,一秒允許請求一次 def limit(seconds=1): #定義內部方法 def rate_limit(func): def func_limit(request): #獲取當前時間 now = time.time() ip
= request.META.get(REMOTE_ADDR) print(int(now)) print(ip) print(- *50) #獲取首次來訪時間 request_time = request.session.get(req_time,0) print(request_time) _ip = request.session.get(ip,ip) print(_ip) #做減法 in_time = int(now) - request_time #判斷訪問者在一秒內來了不止一次 if in_time < seconds and ip == _ip: #拋出異常,使用第二個參數來指定異常 return HttpResponse(你是爬蟲,不要來了,status = 403) else: #存儲第一次請求時間 request.session[req_time] = time.time() request.session[ip] = ip #讓訪問者繼續訪問 ret = func(request) return ret return func_limit return rate_limit # Create your views here. #定義註冊邏輯類視圖 class Reg(View): #定義註冊接收方法 def post(self,request): #等待時間 time.sleep(1) #接收參數 username = request.POST.get(username,未收到username值) password = request.POST.get(password,未收到password值) #註冊入庫邏輯 #先驗證用戶唯一性 res = User.objects.filter(username=username).count() if res > 0: # #該用戶名已被註冊 # #將dict強轉為json數據 # data = json.dumps({‘msg‘:‘該用戶名已被註冊‘},ensure_ascii=False) # #聲明返回網頁頭部信息為json類型 # return HttpResponse(data,content_type=‘application/json‘) return JsonResponse({msg:該用戶名已被註冊}) else: #入庫 #實例化一個對象 user = User(username=username,password=password) #保存 user.save() # #將dict強轉為json數據 # data = json.dumps({‘msg‘:‘恭喜您,註冊成功‘},ensure_ascii=False) # return HttpResponse(data,content_type=‘application/json‘) return JsonResponse({msg:恭喜您,註冊成功},safe=False) #為登錄頁面加上圖形驗證碼的驗證邏輯 from PIL import ImageDraw #導入繪圖字體庫 from PIL import ImageFont #到導入圖片庫 from PIL import Image import io,random #定義隨機顏色方法 def get_random_color(): R = random.randrange(255) G = random.randrange(255) B = random.randrange(255) return (R,G,B) #定義隨機驗證碼 def test_captcha(request): #定義背景顏色 bg_color = get_random_color() #定義畫布大小,寬 高 img_size = (150,80) #定義畫筆,顏色中類,畫布,背景顏色 image = Image.new(RGB,img_size,bg_color) #定義畫筆對象 ,圖片對象,顏色類型 draw = ImageDraw.Draw(image,"RGB") #定義隨機字符 source = 0123456789qwertyuiopasdfghjklzxcvbnm #定義四個字符 #定義容器,用來接收隨機字符串 code_str="" for i in range(4): #獲取隨機顏色 text_color = get_random_color() #獲取隨機字符串 tmp_num = random.randrange(len(source)) #獲取字符集 random_str =source[tmp_num] #將隨機生成的字符串添加到容器中 code_str += random_str #將字符畫動畫布上 坐標,字符串,字符串顏色,字體 #先導入系統字體 my_font = ImageFont.truetype("c:\\Windows/Fonts/consolai.ttf",30) draw.text((10+30*i,20),random_str,text_color,font=my_font) #使用io獲取一個緩存區 buf= io.BytesIO() #將圖片保存到緩存區 透明圖片 image.save(buf,png) #將隨機碼存儲到session中,用於登錄認證 request.session[code] = code_str #第二個參數聲明頭部信息 return HttpResponse(buf.getvalue(),image/png) #定義登錄邏輯類視圖 class Login(View): #定義登錄方法 def post(self,request): # time.sleep(2) #接收參數 username = request.POST.get(username,未收到username值) password = request.POST.get(password,未收到password值) code = request.POST.get(code,未收到code值) #判斷 res = User.objects.filter(username=username,password=password).count() #測試中文用戶名 # return HttpResponse(res) if res > 0 and code == request.session[code]: #登錄成功 response = HttpResponse(登陸成功) #對中文用戶名編碼 username = bytes(username,utf-8).decode(ISO-8859-1) #存入cookie request.COOKIES.get(‘username‘) response.set_cookie(username,username,max_age=3600) response.set_cookie(password,password,max_age=3600) #用戶名存入session request.session[username] = username return response elif res > 0 and code != request.session[code]: return HttpResponse(驗證碼輸入有誤,請重新輸入!) else: #登錄失敗,防止暴力破解 return HttpResponse(您輸入的用戶名或者密碼錯誤,請重新輸入!) #定義註銷功能 class Logout(View): #定義註銷方法 def get(self,request): #建立response對象 response = HttpResponseRedirect(/supermarket/login) #刪除cookie response.delete_cookie(username) response.delete_cookie(password) # #刪除session # del request.session[‘username‘] return response # 定義商品列表頁混合視圖 class ProductList(View): @method_decorator(cookie) #客戶端get請求 def get(self,request): infos = Product.objects.all() print(infos) username = request.COOKIES.get(username,未登錄) #對中文用戶名解碼 try: username = username.encode(ISO-8859-1).decode(utf-8) except Exception as e: print(e) pass #渲染模板 return render(request,supermarket/productList.html,locals()) #商品入庫 class Add(View): def post(self,request): name = request.POST.get(name) price = request.POST.get(price) #只讓不同的商品入庫 ret = Product.objects.filter(name=name,price=int(price)).count() if ret == 0: sql = Product(name=name,price=int(price)) sql.save() return HttpResponse(入庫成功) else: return HttpResponse(該商品已存在) #定義商品刪除操作 class ProDel(View): def post(self,request): #接受參數 id = request.POST.get(id) id=int(id) #刪除操作 Product.objects.filter(id=id).delete() return HttpResponse(刪除成功) #修改操作 class ProEdit(View): def post(self,request): id = request.POST.get(id) id=int(id) name = request.POST.get(name) price = request.POST.get(price) price=int(price) #修改 Product.objects.filter(id=id).update(name=name,price=price) return HttpResponse(修改成功) #添加購物車操作 class AddCart(View): def post(self,request): id = request.POST.get(id) id = int(id) #判斷購物車,是否存在 # cartlist = request.session.get(‘cartlist‘,0) #獲取session的用戶名的購物車 username = request.session.get(username) cartlist = request.session.get(username,0) #如果沒有購物車,就創建後添加 if cartlist == 0: clist = [] clist.append(id) # request.session[‘cartlist‘] = clist request.session[username] = clist #如果有購物車 else: #取出購物車 # slist = request.session[‘cartlist‘] slist = request.session[username] #id直接存入購物車 slist.append(id) #把購物車重新放入session # request.session[‘cartlist‘] = slist request.session[username] = slist return HttpResponse(成功加入購物車) #購物車列表頁 class CartList(View): def get(self,request): # del request.session[‘cartlist‘] # cartlist = request.session.get(‘cartlist‘,0) #獲取個人購物車 username = request.session.get(username,0) cartlist = request.session.get(username,0) #查詢商品數據庫的id字段 idlist = Product.objects.raw("select id from product") #對象列表嵌套數據,用列表推導式和對象.屬性,生成id列表 idlist = [ x.id for x in idlist] # print(idlist) #購物車為空或沒有創建購物車 if cartlist != 0 and cartlist != []: #準備傳給前端的數據 context = [] for i in cartlist: #判斷購物車的商品是否能買 if i in idlist: obj = Product.objects.filter(id=i) # print(‘- ‘*50) # print(obj[0].id)#對象列表嵌套 context.append(obj[0]) #此商品已下架 else: obj = {id:i,name:該商品已下架,price:‘‘} context.append(obj) #沒有創建購物車 elif cartlist == []: context = [] return render(request,supermarket/cartList.html,locals()) #購物車刪除操作 class CartDel(View): def post(self,request): id = request.POST.get(id) id = int(id) # cartlist = request.session.get(‘cartlist‘,0) #獲取session的用戶名的購物車 username = request.session.get(username) cartlist = request.session[username] #remove()會刪除第一個等於指定值的元素 if cartlist != []: cartlist.remove(id) request.session[username] = cartlist return HttpResponse(刪除成功) ‘‘‘ from django.http import JsonResponse 用來對象dumps成json字符串,然後返回將json字符串封裝成Response對象返回給瀏覽器。 並且他的Content-Type是application/json。 非字典只有list,tuple轉json應該在使用HttpResponse的時候,傳入一個safe=False參數 ‘‘‘ def Json(request): ddd = {"username":"知乎大神","age":18} lll = [a,b,c,d] ttt = (1,2,3,4,5,6) return JsonResponse(lll,safe=False)


#導入方法視圖模板 from django.shortcuts import render #導包 from django.http import HttpResponse,HttpResponseRedirect,JsonResponse #導入類視圖 from django.views import View #從配置文件已安裝的django應用模塊導入數據庫類 from mysite.models import User from supermarket.models import Product #導入json import json #導入時間模塊 import time #導入源生sql連接 from django.db import connection
#導入通用類視圖裝飾器 from django.utils.decorators import method_decorator


#定義一個用cookie驗證登錄的裝飾器decorator #用session驗證登錄的裝飾器只需換下變量名,在註銷功能改下即可 def cookie(func): def wrapper(request,*args,**kwargs): login = request.COOKIES.get("username",False) if not login: return HttpResponseRedirect(‘/supermarket/login‘) return func(request,*args,**kwargs) return wrapper

#定義反爬裝飾器,定義形參,一秒允許請求一次 def limit(seconds=1): #定義內部方法 def rate_limit(func): def func_limit(request): #獲取當前時間 now = time.time() ip = request.META.get(‘REMOTE_ADDR‘) print(int(now)) print(ip) print(‘- ‘*50) #獲取首次來訪時間 request_time = request.session.get(‘req_time‘,0) print(request_time) _ip = request.session.get(‘ip‘,ip) print(_ip) #做減法 in_time = int(now) - request_time
#判斷訪問者在一秒內來了不止一次 if in_time < seconds and ip == _ip: #拋出異常,使用第二個參數來指定異常 return HttpResponse(‘你是爬蟲,不要來了‘,status = 403) else: #存儲第一次請求時間 request.session[‘req_time‘] = time.time() request.session[‘ip‘] = ip #讓訪問者繼續訪問 ret = func(request) return ret return func_limit return rate_limit


# Create your views here. #定義註冊邏輯類視圖 class Reg(View):
#定義註冊接收方法 def post(self,request):
#等待時間 time.sleep(1)
#接收參數 username = request.POST.get(‘username‘,‘未收到username值‘) password = request.POST.get(‘password‘,‘未收到password值‘) #註冊入庫邏輯 #先驗證用戶唯一性 res = User.objects.filter(username=username).count() if res > 0: # #該用戶名已被註冊 # #將dict強轉為json數據 # data = json.dumps({‘msg‘:‘該用戶名已被註冊‘},ensure_ascii=False) # #聲明返回網頁頭部信息為json類型 # return HttpResponse(data,content_type=‘application/json‘) return JsonResponse({‘msg‘:‘該用戶名已被註冊‘}) else: #入庫 #實例化一個對象 user = User(username=username,password=password) #保存 user.save() # #將dict強轉為json數據 # data = json.dumps({‘msg‘:‘恭喜您,註冊成功‘},ensure_ascii=False) # return HttpResponse(data,content_type=‘application/json‘) return JsonResponse({‘msg‘:‘恭喜您,註冊成功‘},safe=False)


#為登錄頁面加上圖形驗證碼的驗證邏輯 from PIL import ImageDraw #導入繪圖字體庫 from PIL import ImageFont #到導入圖片庫 from PIL import Image import io,random #定義隨機顏色方法 def get_random_color(): R = random.randrange(255) G = random.randrange(255) B = random.randrange(255) return (R,G,B) #定義隨機驗證碼 def test_captcha(request): #定義背景顏色 bg_color = get_random_color() #定義畫布大小,寬 高 img_size = (150,80) #定義畫筆,顏色中類,畫布,背景顏色 image = Image.new(‘RGB‘,img_size,bg_color) #定義畫筆對象 ,圖片對象,顏色類型 draw = ImageDraw.Draw(image,"RGB") #定義隨機字符 source = ‘0123456789qwertyuiopasdfghjklzxcvbnm‘ #定義四個字符 #定義容器,用來接收隨機字符串 code_str="" for i in range(4): #獲取隨機顏色 text_color = get_random_color() #獲取隨機字符串 tmp_num = random.randrange(len(source)) #獲取字符集 random_str =source[tmp_num] #將隨機生成的字符串添加到容器中 code_str += random_str #將字符畫動畫布上 坐標,字符串,字符串顏色,字體 #先導入系統字體 my_font = ImageFont.truetype("c:\\Windows/Fonts/consolai.ttf",30) draw.text((10+30*i,20),random_str,text_color,font=my_font) #使用io獲取一個緩存區 buf= io.BytesIO() #將圖片保存到緩存區 透明圖片 image.save(buf,‘png‘)
#將隨機碼存儲到session中,用於登錄認證 request.session[‘code‘] = code_str
#第二個參數聲明頭部信息 return HttpResponse(buf.getvalue(),‘image/png‘)




#定義登錄邏輯類視圖 class Login(View):
#定義登錄方法 def post(self,request):
# time.sleep(2)
#接收參數 username = request.POST.get(‘username‘,‘未收到username值‘) password = request.POST.get(‘password‘,‘未收到password值‘) code = request.POST.get(‘code‘,‘未收到code值‘)
#判斷 res = User.objects.filter(username=username,password=password).count() #測試中文用戶名 # return HttpResponse(res) if res > 0 and code == request.session[‘code‘]: #登錄成功 response = HttpResponse(‘登陸成功‘) #對中文用戶名編碼 username = bytes(username,‘utf-8‘).decode(‘ISO-8859-1‘) #存入cookie request.COOKIES.get(‘username‘) response.set_cookie(‘username‘,username,max_age=3600) response.set_cookie(‘password‘,password,max_age=3600) #用戶名存入session request.session[‘username‘] = username return response elif res > 0 and code != request.session[‘code‘]: return HttpResponse(‘驗證碼輸入有誤,請重新輸入!‘) else: #登錄失敗,防止暴力破解 return HttpResponse(‘您輸入的用戶名或者密碼錯誤,請重新輸入!‘)


#定義註銷功能 class Logout(View): #定義註銷方法 def get(self,request): #建立response對象 response = HttpResponseRedirect(‘/supermarket/login‘) #刪除cookie response.delete_cookie(‘username‘) response.delete_cookie(‘password‘) # #刪除session # del request.session[‘username‘] return response
# 定義商品列表頁混合視圖 class ProductList(View):
@method_decorator(cookie) #客戶端get請求 def get(self,request): infos = Product.objects.all() print(infos) username = request.COOKIES.get(‘username‘,‘未登錄‘) #對中文用戶名解碼 try: username = username.encode(‘ISO-8859-1‘).decode(‘utf-8‘) except Exception as e: print(e) pass #渲染模板 return render(request,‘supermarket/productList.html‘,locals())

#商品入庫 class Add(View):
def post(self,request): name = request.POST.get(‘name‘) price = request.POST.get(‘price‘) #只讓不同的商品入庫 ret = Product.objects.filter(name=name,price=int(price)).count() if ret == 0: sql = Product(name=name,price=int(price)) sql.save() return HttpResponse(‘入庫成功‘) else: return HttpResponse(‘該商品已存在‘)


#定義商品刪除操作 class ProDel(View): def post(self,request): #接受參數 id = request.POST.get(‘id‘) id=int(id) #刪除操作 Product.objects.filter(id=id).delete() return HttpResponse(‘刪除成功‘)


#修改操作 class ProEdit(View):
def post(self,request): id = request.POST.get(‘id‘) id=int(id) name = request.POST.get(‘name‘) price = request.POST.get(‘price‘) price=int(price) #修改 Product.objects.filter(id=id).update(name=name,price=price) return HttpResponse(‘修改成功‘)


#添加購物車操作 class AddCart(View):
def post(self,request): id = request.POST.get(‘id‘) id = int(id) #判斷購物車,是否存在 # cartlist = request.session.get(‘cartlist‘,0)
#獲取session的用戶名的購物車 username = request.session.get(‘username‘) cartlist = request.session.get(username,0) #如果沒有購物車,就創建後添加 if cartlist == 0: clist = [] clist.append(id) # request.session[‘cartlist‘] = clist request.session[username] = clist #如果有購物車 else: #取出購物車 # slist = request.session[‘cartlist‘] slist = request.session[username] #id直接存入購物車 slist.append(id) #把購物車重新放入session # request.session[‘cartlist‘] = slist request.session[username] = slist return HttpResponse(‘成功加入購物車‘)


#購物車列表頁 class CartList(View):
def get(self,request): # del request.session[‘cartlist‘]
# cartlist = request.session.get(‘cartlist‘,0)
#獲取個人購物車 username = request.session.get(‘username‘,0) cartlist = request.session.get(username,0)
#查詢商品數據庫的id字段 idlist = Product.objects.raw("select id from product") #對象列表嵌套數據,用列表推導式和對象.屬性,生成id列表 idlist = [ x.id for x in idlist] # print(idlist)
#購物車為空或沒有創建購物車 if cartlist != 0 and cartlist != []: #準備傳給前端的數據 context = [] for i in cartlist: #判斷購物車的商品是否能買 if i in idlist: obj = Product.objects.filter(id=i) # print(‘- ‘*50) # print(obj[0].id)#對象列表嵌套 context.append(obj[0]) #此商品已下架 else: obj = {‘id‘:i,‘name‘:‘該商品已下架‘,‘price‘:‘‘} context.append(obj) #沒有創建購物車 elif cartlist == []: context = ‘[]‘
return render(request,‘supermarket/cartList.html‘,locals())

#購物車刪除操作 class CartDel(View):
def post(self,request): id = request.POST.get(‘id‘) id = int(id) # cartlist = request.session.get(‘cartlist‘,0) #獲取session的用戶名的購物車 username = request.session.get(‘username‘) cartlist = request.session[username]
#remove()會刪除第一個等於指定值的元素 if cartlist != []: cartlist.remove(id) request.session[username] = cartlist
return HttpResponse(‘刪除成功‘)

‘‘‘ from django.http import JsonResponse 用來對象dumps成json字符串,然後返回將json字符串封裝成Response對象返回給瀏覽器。 並且他的Content-Type是application/json。 非字典只有list,tuple轉json應該在使用HttpResponse的時候,傳入一個safe=False參數 ‘‘‘ def Json(request): ddd = {"username":"知乎大神","age":18} lll = [‘a‘,‘b‘,‘c‘,‘d‘] ttt = (1,2,3,4,5,6) return JsonResponse(lll,safe=False)

Django子應用裏的通用類混合視圖處理