web後端--Django學習筆記09
阿新 • • 發佈:2018-11-14
一、第八天作業
1、在登錄檔單中包括使用者名稱、密碼、性別、愛好(可以有多個),還要完成上傳頭像,要求在伺服器完成接收資料,並儲存到伺服器。
1.1 程式碼演示
1、views
from django.http import HttpResponse from django.shortcuts import render import os BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) def go_register(request): return render(request,'homework/register.html') def register(request): regname = request.POST["regname"] regpwd = request.POST["regpwd"] sex = request.POST["sex"] hobbies = request.POST.getlist("hobby") # 接收一組引數 your_figure = request.FILES.get("your_figure") print("註冊名是:"+regname) print("註冊密碼是:" + regpwd) print("註冊性別是:" + sex) print("您的愛好是:",hobbies) dest_path = os.path.join(BASE_DIR,'upload','images',your_figure.name) with open(dest_path,'wb') as f: for chunk in your_figure.chunks(): f.write(chunk) return HttpResponse("註冊成功!")
2、templates
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>註冊頁面</title> </head> <body> <form action="{% url 'home:register' %}" method="post" enctype="multipart/form-data"> {% csrf_token %} 註冊使用者名稱:<input type="text" name="regname"/> <br/> 註冊密碼:<input type="password" name="regpwd"/> <br/> 性別:男:<input type="radio" name="sex" value="boy" checked="checked"/> 女:<input type="radio" name="sex" value="girl"/> <br/> 愛好:讀書<input type="checkbox" name="hobby" value="read"/> 電影<input type="checkbox" name="hobby" value="movie"/> 跑步<input type="checkbox" name="hobby" value="jogging"/> 美食<input type="checkbox" name="hobby" value="food"/> 音樂<input type="checkbox" name="hobby" value="music"/> 個人頭像:<input type="file" name="your_figure"/> <br/> <input type="submit" value="註冊"/> </form> </body> </html>
3、urls
#子路由 from django.urls import path from homework.views import * app_name = 'homework' urlpatterns = [ path('goreg/',go_register), path('register/',register,name="register"), ] #總路由 path('homework/',include('homework.urls',namespace='home')),
二、Django資料庫快取
第一步:建立快取表 python manage.py createcachetable 自定義快取表名稱 例:python manage.py createcachetable mycachetable
第二步: 在settings.py中設定快取為資料庫表 CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.db.DatabaseCache', 'LOCATION': '快取表名稱', } } 第三步:程式操作 def get_product_byid(request,product_id): # 使用底層from django.core.cache import cache查詢快取 product = cache.get("key") if 快取中存在: 快取命中,直接返回 else: product = Product.objects.get(id=product_id) # 從資料庫中查詢 cache.set("key",product,"可以傳入快取過期時間") # 儲存到快取表中 return 返回給客戶端
2.1 程式碼演示
1、setting
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.db.DatabaseCache', 'LOCATION': 'mycachetable', } } #更改時區 TIME_ZONE = 'Asia/Shanghai' #亞洲上海 USE_I18N = True USE_L10N = True USE_TZ = False #否定預設時區
2、models
from django.db import models class Product(models.Model): name = models.CharField(max_length=20) price = models.FloatField() class Meta: db_table = 'products'
3、views
from django.core.cache import cache from django.shortcuts import render from django.views.decorators.cache import cache_page from cacheapp.models import Product def get_product_byid(request,product_id): product = cache.get('product:'+str(product_id)) # 使用底層API查詢快取 if product: msg = "恭喜,快取命中了" else: product = Product.objects.get(id=product_id) # 從資料庫中查詢 msg = "快取中沒找到,只有查資料庫了!" cache.set('product:'+str(product.id),product,30) # 儲存到快取表中 return render(request, 'cacheapp/product.html', locals()) # @cache_page(30) #裝飾器,定義快取過期時間 def get_all_products(request): #查詢所有產品 print("準備查詢所有產品~~~") products = Product.objects.all() print("已經查詢完畢所有產品~~~") return render(request,'cacheapp/all_products.html',locals())
4、templates
<!product.html> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>產品模板</title> </head> <body> <h3 style="color:red">{{ msg }}</h3> <h3>產品編號:{{ product.id }}</h3> <h3>產品名稱:{{ product.name }}</h3> <h3>產品價格:{{ product.price }}</h3> </body> </html>
<!all_products.html> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>所有產品資訊</title> </head> <body> <table align="center" border="1"> <thead> <tr> <th>產品編號</th> <th>產品名稱</th> <th>產品價格</th> </tr> </thead> <tbody> {% for product in products %} <tr> <td> {{ product.id }} </td> <td> {{ product.name }} </td> <td> {{ product.price }} </td> </tr> {% endfor %} </tbody> </table> </body> </html>
5、urls
#子路由 from django.urls import path from cacheapp.views import * urlpatterns = [ path('product/<int:product_id>/',get_product_byid), path('products/',cache_page(30)(get_all_products)), path('allproducts/',get_all_products), ] #總路由 path('cacheapp/',include('cacheapp.urls')),
6、MySQL
mysql> create database mydb default character set utf8; Query OK, 1 row affected (0.01 sec) mysql> use mydb; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> desc mycachetable; #檢視建立的快取表 +-----------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-----------+--------------+------+-----+---------+-------+ | cache_key | varchar(255) | NO | PRI | NULL | | | value | longtext | NO | | NULL | | | expires | datetime(6) | NO | MUL | NULL | | +-----------+--------------+------+-----+---------+-------+ 3 rows in set (0.00 sec) mysql> insert into products(name,price)values('電腦',6000),('箱子',60); Query OK, 2 rows affected (0.01 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> select * from products; +----+--------+-------+ | id | name | price | +----+--------+-------+ | 1 | 電腦 | 6000 | | 2 | 箱子 | 60 | +----+--------+-------+ 2 rows in set (0.00 sec) mysql> select * from mycachetable\G; *************************** 1. row *************************** cache_key: :1:product:1 value: gASVyQAAAAAAAACMFWRqYW5nby5kYi5tb2RlbHMuYmFzZZSMDm1vZGVsX3VucGlja2xllJOUjAhjYWNoZWFwcJSMB1Byb2R1Y3SUhpSFlFKUfZQojAZfc3RhdGWUaACMCk1vZGVsU3RhdGWUk5QpgZR9lCiMBmFkZGluZ5SJjAJkYpSMB2RlZmF1bHSUdWKMAmlklEsBjARuYW1llIwG55S16ISRlIwFcHJpY2WUR0C3cAAAAAAAjA9fZGphbmdvX3ZlcnNpb26UjAUyLjEuMpR1Yi4= expires: 2018-11-13 21:39:14.000000 *************************** 2. row *************************** cache_key: :1:product:2 value: gASVyQAAAAAAAACMFWRqYW5nby5kYi5tb2RlbHMuYmFzZZSMDm1vZGVsX3VucGlja2xllJOUjAhjYWNoZWFwcJSMB1Byb2R1Y3SUhpSFlFKUfZQojAZfc3RhdGWUaACMCk1vZGVsU3RhdGWUk5QpgZR9lCiMBmFkZGluZ5SJjAJkYpSMB2RlZmF1bHSUdWKMAmlklEsCjARuYW1llIwG566x5a2QlIwFcHJpY2WUR0BOAAAAAAAAjA9fZGphbmdvX3ZlcnNpb26UjAUyLjEuMpR1Yi4= expires: 2018-11-13 21:39:30.000000 2 rows in set (0.00 sec) ERROR: No query specified mysql>
三、快取頁面(檢視函式的執行結果)
第一種使用方法: 在檢視函式上新增@cache_page(快取秒數)裝飾器,則會對檢視結果快取 指定的秒數。快取到CACHES指定的快取地址。
第二種使用方法: path("url/",cache_page(快取秒數)(檢視函式名稱)) 注意:cache_page是針對於具體的URL來進行快取的。
3.1 程式碼演示 (同2.1)
四、自定義表單類
1.繼承Form類(django.forms.Form),編寫表單類 class RegForm(forms.Form): # 自定義表單類,繼承Form類 regname = forms.CharField(label="註冊使用者名稱",max_length=10) regpwd = forms.CharField(label="註冊密碼",widget=forms.PasswordInput()) reghome = forms.ChoiceField(label="籍貫",choices=(("1","陝西"),("2","北京"),("3","山東"))) sex = forms.ChoiceField(label="性別",choices=(("0","男"),("1","女")),widget=forms.RadioSelect())
2. 在檢視函式中判斷提交方式,對錶單做出不同處理 def register(request): if request.method == "POST": regform = RegForm(request.POST) # 將POST資料傳入表單物件的構造方法中 if regform.is_valid(): # 驗證表單資料是否有效 regname = regform.cleaned_data["regname"] # 接收指定表單域的資料 print("家鄉:"+reghome+";性別:",regsex) return redirect(reverse("formapp:success",args=(regname,regpwd))) else: regform = RegForm() # 例項化一個空的表單物件 return render(request,'formapp/register.html',{"regform":regform}) 3. 在模板上渲染表單 <form action="" method="post"> {% csrf_token %} {{ regform.as_p }} 顯示錶單物件封裝的表單控制元件 <input type="submit" value="註冊"/> </form>
4.1 程式碼演示
1、forms.py
from django import forms class RegForm(forms.Form): # 自定義表單類,繼承Form類 regname = forms.CharField(label="註冊使用者名稱",max_length=10) regpwd = forms.CharField(label="註冊密碼",widget=forms.PasswordInput()) reghome = forms.ChoiceField(label="籍貫",choices=(("1","陝西"),("2","北京"),("3","山東"))) sex = forms.ChoiceField(label="性別",choices=(("0","男"),("1","女")),widget=forms.RadioSelect())
2、views
from django.shortcuts import render, redirect from django.urls import reverse from formapp.forms import RegForm def go_success(request,regname,regpwd): return render(request,'formapp/success.html',locals()) def register(request): if request.method == "POST": regform = RegForm(request.POST) # 將POST資料傳入表單物件的構造方法中 if regform.is_valid(): # 驗證表單資料是否有效 regname = regform.cleaned_data["regname"] # 接收指定表單域的資料 regpwd = regform.cleaned_data["regpwd"] reghome = regform.cleaned_data["reghome"] regsex = regform.cleaned_data["sex"] print("家鄉:"+reghome+";性別:",regsex) return redirect(reverse("formapp:success",args=(regname,regpwd))) else: regform = RegForm() # 例項化一個空的表單物件 return render(request,'formapp/register.html',{"regform":regform})
3、templates
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>註冊頁面</title> </head> <body> <form action="" method="post"> {% csrf_token %} {{ regform.as_p }} <!以p標籤展示> <input type="submit" value="註冊"/> </form> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>成功頁面</title> </head> <body> <h3> 註冊成功,註冊的使用者名稱是:{{ regname }},密碼是:{{ regpwd }} </h3> </body> </html>
4、urls
from django.urls import path,include from formapp.views import * app_name = "formapp" urlpatterns = [ path('register/',register,name="register"), path('gosuccess/<regname>/<regpwd>/',go_success,name="success"), ]
五、自定義錯誤頁面
在專案的總路由配置檔案中將預設的錯誤處理程式設定為自定義的檢視函式 eg: from django.conf.urls import handler500 handler500 = 自定義檢視函式名稱
]注意:兩個設定 在settings.py中,要將除錯狀態關閉,並設定ALLOWED_HOSTS: DEBUG = False ALLOWED_HOSTS = ["*"] 如果使用的是Django自帶的開發伺服器,則不能直接在自定義的錯誤頁面中 載入靜態資源;如果要載入靜態資源,需要使用 "python manage.py runserver --insecure"命令啟動開發伺服器。
5.1 程式碼演示
1、urls
#子路由 from django.urls import path from errorapp.views import * urlpatterns = [ path('error/',error_view), path('miss/',error_404), ] #總路由 from django.conf.urls import handler500, handler404 from django.contrib import admin from django.urls import path,include from errorapp.views import myhandler500,myhandler404 handler500 = myhandler500 handler404 = myhandler404 urlpatterns = [ path('admin/', admin.site.urls), path('errorapp/',include('errorapp.urls')), ]
2、views
from django.http import HttpResponse, HttpResponseRedirect from django.shortcuts import render def error_view(request): 5 / 0 return HttpResponse("Hello") def error_404(request): return HttpResponseRedirect("/abc/") def myhandler500(request): return render(request,'errorapp/my500.html') def myhandler404(request): return render(request,'errorapp/my404.html')
3、templates
<!DOCTYPE html> {% load static %} <html lang="en"> <head> <meta charset="UTF-8"> <title>500</title> </head> <body> <h3>發生一點小故障~~~</h3> <img src="{% static 'errorapp/images/ren.gif' %}"/> </body> </html>