一、第五天作业
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 %}