web後端--Django學習筆記06
一、第五天作業
1、 丈夫和妻子是“一對一”的關係,通過模型建立相關表,並插入相關記錄, 並查詢某個丈夫對應的妻子;某個妻子對應的丈夫; 並進行級聯刪除;
2、 通過反向解析生成url,並點選超連結完成查詢某個產品的功能, 然後改變對應的url,體會反向解析的好處。
1、models
# husband_wife from django.db import models class Husband(models.Model): name = models.CharField(max_length=20) age = models.IntegerField() def __str__(self): return self.name class Meta: db_table = 'husbands' class Wife(models.Model): name = models.CharField(max_length=20) age = models.IntegerField() husband = models.OneToOneField(Husband,on_delete=models.CASCADE) def __str__(self): return self.name class Meta: db_table = 'wives'
# product.py from django.db import models class Product(models.Model): name = models.CharField(max_length=20) price = models.FloatField() def __str__(self): return self.name class Meta: db_table = 'products'
2、templates
<!products.html> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>所有產品</title> </head> <body> {% for product in products %} <a href="{% url 'home:product_detail' product.id %}"> {{ product.name }} </a> <hr/> {% endfor %} </body> </html>
<! product_detail.html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>產品ID:{{ product.id }}</h3>
<h3>產品名稱:{{ product.name }}</h3>
<h3>產品價格:{{ product.price }}</h3>
</body>
</html>
3、view
from django.shortcuts import render
from homework.models import Product
def go_products(request):
products = Product.objects.all()
return render(request,'products.html',locals())
def product_detail(request,product_id):
product = Product.objects.get(id=product_id)
return render(request, 'product_detail.html', locals())
4、urls
#總路由
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('admin/', admin.site.urls),
path('homework/', include('homework.urls', namespace='home')),
]
#子路由
from django.urls import path
from homework.views import *
app_name = 'homework'
urlpatterns = [
path('goproduct/',go_products),
path('detail/<product_id>/',product_detail,name="product_detail"),
]
5、Terminal
crosoft Windows [版本 10.0.17763.55]
(c) 2018 Microsoft Corporation。保留所有權利。
C:\python\DjangoDay6>python manage.py makemigrations #遷移計劃
C:\python\DjangoDay6>python manage.py migrate #遷移
C:\python\DjangoDay6>python manage.py shell #進入shell
>>> from homework.models import *
>>> pro1 = Product(name='汰漬洗衣粉',price=12.5)
>>> pro1.save()
>>> pro2 = Product(name='辣條',price=1.50)
>>> pro2.save()
>>> exit()
C:\python\DjangoDay6>python manage.py runserver #啟動伺服器
6、MySQL
mysql> use mydb
Database changed
mysql> show tables;
+----------------------------+
| Tables_in_mydb |
+----------------------------+
| auth_group |
| auth_group_permissions |
| auth_permission |
| auth_user |
| auth_user_groups |
| auth_user_user_permissions |
| django_admin_log |
| django_content_type |
| django_migrations |
| django_session |
| husbands |
| products |
| wives |
+----------------------------+
13 rows in set (0.01 sec)
mysql> select * from products;
+----+-----------------+-------+
| id | name | price |
+----+-----------------+-------+
| 1 | 汰漬洗衣粉 | 12.5 |
+----+-----------------+-------+
1 row in set (0.00 sec)
mysql> select * from products;
+----+-----------------+-------+
| id | name | price |
+----+-----------------+-------+
| 1 | 汰漬洗衣粉 | 12.5 |
| 2 | 辣條 | 1.5 |
+----+-----------------+-------+
2 rows in set (0.00 sec)
7、browser
http://localhost:8000/homework/goproduct/
二、重定向的redirect()方式
使用HttpResponseRedirect傳參方式: return HttpResponseRedirect('url?引數名1=引數值1&引數名2=引數值2') # 重定向,並傳參
redirect()函式與reverse()結合使用,可以動態解析URL
使用kwargs對應的字典傳參(通過字典key-value對映到反向解析出的URL)return redirect(reverse('namespace:name',kwargs={"key1":value1,"key2":value2}))
使用args對應的元祖傳參(按照捕獲引數的順序傳遞)return redirect(reverse('namespace:name',args=(元素1,元素2)))
2.1 程式碼演示
1、views
from django.http import HttpResponseRedirect
from django.shortcuts import render, redirect
from django.urls import reverse
def gologin(request):
return render(request,'login.html')
def login(request):
login_name = request.POST["login_name"]
login_pwd = request.POST["login_pwd"]
if login_name =="tom" and login_pwd =="12345":
request.session["login_name"] =login_name#登陸成功後設置一個sesssion
return render(request,'success.html',{"loginname":login_name})
else:
# return HttpResponseRedirect('/redirecttest/wronglogin/?logname='+ login_name)#重定向並傳參
# 使用名稱空間和名稱重定向,使用args對應的元祖傳參
#return redirect(reverse('redirect:wrongloing',args=(login_name,login_pwd))) #使用名稱空間並傳參
# 使用名稱空間和名稱重定向,使用kwargs對應的字典傳參
return redirect(reverse('redirect:wrongloing',kwargs={"userpwd":login_pwd,"username":login_name}))
def go_login_withwrong(request,username,userpwd):
# logname =request.GET["logname"]
msg = "使用者名稱或密碼錯誤"
return render(request,'login.html',locals())
2、templates
<!login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登陸頁面</title>
</head>
<body>
<h3 style="color: red">{{ msg }}</h3>
{% if username %}
<h3>錯誤的使用者名稱:{{ username}}</h3>
<h3>錯誤的密碼:{{ userpwd }}</h3>
{% endif %}
<form action="{% url 'redirect:userlogin' %}" method="post">
{% csrf_token %}
使用者名稱:<input type="text" name="login_name"><br/>
密碼:<input type="password" name="login_pwd"><br/>
<input type="submit" value="登入">
</form>
</body>
</html>
<!success.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登入成功</title>
</head>
<body>
<h3>恭喜,<span style="color: green">{{ loginname }}</span> 登陸成功</h3>
</body>
</html>
3、urls
#子路由
from django.urls import path
from redirectapp.views import *
app_name = "rediectapp"
urlpatterns = [
path('gologin/', gologin),
path('login/',login,name='userlogin'),
path('wronglogin/<username>/<userpwd>',go_login_withwrong,name="wrongloing")
]
#總路由
path('redirecttest/',include('redirectapp.urls',namespace="redirect"))
三、Cookie與Session
Cookie是服務端建立,但保存於客戶端,客戶端每次傳送請求時都會將Cookie資訊 傳送到伺服器,如果存在一個儲存著sessionid的Cookie,則該Cookie被服務端接收 後,獲取攜帶的sessionid,並將客戶端傳送的sessionid與服務端儲存的sessionid 進行匹配。
Session是用來表示一個使用者與服務端的一次“會話”。使用客戶端傳送的sessionid與服務端的sessionid匹配,找到客戶端所屬的“會話”,經常用於登入驗證。
Django中的Session資訊保存於伺服器端,預設保存於資料庫表中。
設定Cookie:使用HttpResponse物件新增Cookie 例如: response = HttpResponse("Cookie已經設定完畢!") response.set_cookie("Cookie名稱","Cookie值",儲存時間秒數)
操作Session: 新增session: request.session["屬性名"] = 屬性值 刪除session中的某屬性: del request.session["屬性名"]
重要配置(settings.py):
SESSION_EXPIRE_AT_BROWSER_CLOSE = True # 當瀏覽器關閉時,清除本地Cookie
SESSION_COOKIE_AGE = 60 # 設定session儲存的秒數
3.1程式碼演示
1、views
from django.http import HttpResponse
from django.shortcuts import render
def go_session(request):
return render(request, 'session.html')
def add_session(request):
request.session["color"]='green' #給session新增一個color的屬性,屬性值為green
print("新增session的color屬性:",request.session["color"])
return render(request,'session.html')
def delete_session(request):
del request.session["color"]
return render(request,'session.html')
def go_cookies(request):
return render(request,'cookies.html')
def add_cookies(request):
response =HttpResponse("Cookies已經設定完畢")
response.set_cookie("quqi","aa",30)#設定cookies,cookies名稱為quqi,值為"曲奇餅乾",儲存30秒
response.set_cookie("fruit","apple",30)
response.set_cookie("dynast","nansong")
return response
2、templates
<!session.html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>顯示session的id</title>
</head>
<body>
<h3>當前的session是:{{ request.session }}</h3>
<h3>當前的sessionid是:{{ request.session.session_key }}</h3>
</body>
</html>
<!cookie.htnl>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>顯示所有cookies</title>
</head>
<body>
<h3>所有的cookie資訊</h3>
{% for k,v in request.COOKIES.items %}
<h3>{{ k }}======>{{ v }}</h3>
{% endfor %}
</body>
</html>
3、urls
#子路由
from django.urls import path
from sessionapp.views import *
urlpatterns = [
path('gosession/',go_session),
path('addsession/',add_session),
path('del/',delete_session),
path('gocookie/',go_cookies),
path('addcookie/',add_cookies)
]
#總路由
path('sessionapp/',include('sessionapp.urls')),
四、登入驗證
當用戶登入成功時(使用者名稱和密碼都正確),則給當前會話中設定一個屬性。 在只有登入成功才有許可權訪問的頁面,通過判斷當前使用者的會話中是否有 相關屬性,決定當前使用者是否能檢視頁面。
{% if request.session.設定的session屬性名 %} 當用戶登入成功時,顯示此處 {% else %} 當用戶還未登入時,顯示此處{% endif %}