django 提供了比较完善的后台管理数据库的接口,可供开发过程中调用和测试使用
django 会搜集所有已注册的模型类,为这些模型类提拱数据管理界面,供开发者使用
创建后台管理帐号:
[root@vm mysite2]# python3 manage.py createsuperuser
/root/mysite2
用户名 (leave blank to use 'root'): tarena
电子邮件地址: 123456@qq.com
Password:
[root@vm mysite2]# mysql -uroot -p123456 -e 'select * from mysite2.auth_user\G'
*************************** 1. row ***************************
id: 1
password: pbkdf2_sha256$150000$yE0lYzKHcN9i$VShFRN+WFSWd4qOuZDdnEJIi0j0b3u2XHZMJMuQuPvQ=
last_login: NULL
is_superuser: 1
username: tarena
first_name:
last_name:
email: 123456@qq.com
is_staff: 1
is_active: 1
后台管理的登录地址: http://127.0.0.1:8000/admin/ tarena 123456
Django提供了完善的后台管理功能,也是一个完善的用户权限管理模块。登录到后台,我们可以管理系统的提供的用户、组、权限等信息。也可以管理用户的模型类呢?例如:Book类。
若要自己定义的模型类也能在 /admin
后台管理界中显示和管理,需要将自己的类注册到后台管理界面。添加自己定义模型类的后台管理数据表的,需要用admin.site.register(自定义模型类)
方法进行注册
在应用app中的admin.py中导入models类,并注册
[root@vm mysite2]# vim bookstore/admin.py
from django.contrib import admin
# Register your models here.
from .models import Book #导入
admin.site.register(Book) #注册
XXXX object
类型的记录,不便于阅读和判断def __str__(self):
方法解决显示问题,如:
class Book(models.Model):
...
def __str__(self):
return "书名" + self.title
[root@vm mysite2]# cat bookstore/models.py
from django.db import models
# Create your models here.
class Book(models.Model):
title = models.CharField("书名", max_length=50, default='')
price = models.DecimalField('定价', max_digits=7,decimal_places=2, default=0.0)
# 新增属性/字段 (要有默认值)
market_price = models.DecimalField("零售价", max_digits=5,decimal_places=2,default=0.0)
pub = models.CharField("出版社", max_length=50,default="")
def __str__(self):
info = "书名: %s, 出版社: %s, 定价: %s" % (self.title, self.pub, self.price)
return info
作用: 为后台管理界面添加便于操作的新功能。
说明: 后台管理器类须继承自 django.contrib.admin
里的 ModelAdmin
类
模型管理器的使用方法:
在 <应用app>/admin.py
里定义模型管理器类
class XXXXManager(admin.ModelAdmin):
......
绑定注册模型管理器和模型类
admin.site.register(YYYY, XXXXManager) # 绑定YYYY 模型类与管理器类XXXManager
示例:
# file : bookstore/admin.py
from django.contrib import admin
from .models import Book
class BookManager(admin.ModelAdmin):
list_display = ['id', 'title', 'price', 'market_price']
admin.site.register(Book, BookManager)
进入http://127.0.0.1:8000/admin/bookstore/book/ 查看显示方式和以前有所不同
# file : bookstore/admin.py
from django.contrib import admin
from .models import Book
class BookManager(admin.ModelAdmin):
list_display = ['id', 'title', 'price', 'market_price']
ist_display_links =['id', 'title', 'price']
list_filter = ['pub']
search_fields = ['id','title']
list_editable = []
admin.site.register(Book, BookManager)
模型类可以通过定义内部类class Meta 来重新定义当前模型类和数据表的一些属性信息,一般不建议使用
用法格式如下:
class Book(models.Model):
title = CharField(....)
class Meta:
1. db_table = '数据表名'
- 该模型所用的数据表的名称。(设置完成后需要立马更新同步数据库)
2. verbose_name = '单数名'
- 给模型对象的一个易于理解的名称(单数),用于显示在/admin管理界面中
3. verbose_name_plural = '复数名'
- 该对象复数形式的名称(复数),用于显示在/admin管理界面中
...
class Meta:
verbose_name = '图书'
verbose_name_plural = '图书'
在后台/admin管理界面中 ,站点管理之前显示 books,现在显示图书
#新建项目,初始化配置
[root@vm mysite5]# mysql -uroot -p123456 -e 'create database mysite5 default charset utf8;'
[root@vm ~]# django-admin startproject mysite5
[root@vm ~]# cd mysite5/
[root@vm mysite5]# vim mysite5/settings.py
ALLOWED_HOSTS = ['*',]
DATABASES = {
'default' : {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mysite5',
'USER': 'root',
'PASSWORD': '123456',
'HOST': '127.0.0.1',
'PORT': 3306,
}
}
LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = "Asia/Shanghai"
[root@vm mysite5]# python3 manage.py runserver 0.0.0.0:8000
常用的表关联方式有三种:
语法
class A(model.Model):
...
class B(model.Model):
属性 = models.OneToOneField(A, on_delete=xxx)
外键类字段选项,特殊字段参数on_delete【必须项】:
models.CASCADE 级联删除。 Django模拟SQL约束ON DELETE CASCADE的行为,并删除包含ForeignKey的对象。
models.PROTECT 抛出ProtectedError 以阻止被引用对象的删除;[等同于mysql默认的RESTRICT]
models.SET_NULL 设置ForeignKey null;需要指定null=True
models.SET_DEFAULT 将ForeignKey设置为其默认值;必须设置ForeignKey的默认值。
其它参请参考文档 https://docs.djangoproject.com/en/2.2/ref/models/fields/#foreignkey
其余常用的字段选项【非必须项】;如: null , unique 等
用法示例
创建作家和作家妻子类
[root@vm mysite5]# python3 manage.py startapp oto
[root@vm mysite5]# vim mysite5/settings.py
INSTALLED_APPS = [
...
'oto',[root@vm mysite5]# vim oto/models.py
from django.db import models
class Author(models.Model):
'''作家模型类'''
# 有一个反向属性,wife。下面会提到
name = models.CharField('作家', max_length=50)
class Wife(models.Model):
'''作家妻子模型类'''
name = models.CharField("妻子", max_length=50)
author = models.OneToOneField(Author,on_delete=models.CASCADE) # 增加一对一属性 author规范一下写法是关联Author类的小写
#CASCADE 将产生级联删除
[root@vm mysite5]# python3 manage.py makemigrations
[root@vm mysite5]# python3 manage.py migrate
[root@vm mysite5]# mysql -uroot -p123456 -e 'desc mysite5.oto_author;'
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(50) | NO | | NULL | |
+-------+-------------+------+-----+---------+----------------+
[root@vm mysite5]# mysql -uroot -p123456 -e 'desc mysite5.oto_wife;'
+-----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(50) | NO | | NULL | |
| author_id | int(11) | NO | UNI | NULL | |
+-----------+-------------+------+-----+---------+----------------+
使用对象关联或主键关联
[root@vm mysite5]# python3 manage.py shell
from oto.models import *
author1 = Author.objects.create(name='王老师')
wife1 = Wife.objects.create(name='王夫人', author=author1) # 对象关联王老师
author2 = Author.objects.create(name='张老师') # 主键关联的第二种方式
wife1 = Wife.objects.create(name='张夫人', author_id=author2.id)
>>> author3 = Author.objects.create(name='小李老师') #创建无关联的数据,主表数据可以比从表多
> select * from oto_author;
+----+-----------+
| id | name |
+----+-----------+
| 1 | 王老师 |
| 2 | 张老师 |
| 3 | 小李老师 |
+----+-----------+
> select * from oto_wife;
+----+-----------+-----------+
| id | name | author_id |
+----+-----------+-----------+
| 1 | 王夫人 | 1 |
| 2 | 张夫人 | 2 |
+----+-----------+-----------+
#CASCADE 将产生级联删除
>>> Author.objects.get(id=1).delete()
(2, {'oto.Wife': 1, 'oto.Author': 1}) #王夫人随之删除
>>> Wife.objects.get(id=2).delete()
(1, {'oto.Wife': 1}) #张老师不受影响
> select * from oto_author;
+----+--------------+
| id | name |
+----+--------------+
| 2 | 张老师 |
| 3 | 小李老师 |
+----+--------------+
2 rows in set (0.00 sec)
> select * from oto_wife;
Empty set (0.00 sec)
添加数据
>>> wife1 = Wife.objects.create(name='张夫人', author_id=author2.id)
>>> author1 = Author.objects.create(name='王老师')
>>> wife1 = Wife.objects.create(name='王夫人', author=author1)
> select * from oto_author;
+----+--------------+
| id | name |
+----+--------------+
| 2 | 张老师 |
| 3 | 小李老师 |
| 4 | 王老师 |
+----+--------------+
> select * from oto_wife;
+----+-----------+-----------+
| id | name | author_id |
+----+-----------+-----------+
| 3 | 张夫人 | 2 |
| 4 | 王夫人 | 4 |
+----+-----------+-----------+
正向查询:直接通过关联属性查询即可
# 通过 wife 找 author
from oto.models import Wife
wife = Wife.objects.get(name='王夫人')
print(wife.name, '的老公是', wife.author.name)#王夫人 的老公是 王老师
反向查询
实例对象.引用类名(小写)
,如作家的反向引用为作家对象.wife
# 通过 author.wife 关联属性 找 wife,如果没有对应的wife则触发异常
author1 = Author.objects.get(name='王老师')
print(author1.name, '的妻子是', author1.wife.name)
author2 = Author.objects.get(name='小李老师')
try:
print(author2.name, '的妻子是', author2.wife.name)
except:
print(author2.name, '还没有妻子')
#小李老师 还没有妻子
一对多是表示现实事物间存在的一对多的对应关系。语法:当一个A类对象可以关联多个B类对象时
class A(model.Model):
...
class B(model.Model):
属性 = models.ForeignKey("一"的模型类, on_delete=xx)
[root@vm mysite5]# python3 manage.py startapp otm
[root@vm mysite5]# vim mysite5/settings.py
INSTALLED_APPS = [
...
'otm',
[root@vm mysite5]# vim otm/models.py
from django.db import models
class Publisher(models.Model):
# 有一个反向属性,book_set
name = models.CharField("名称", max_length=50,
unique=True)
class Book(models.Model):
title = models.CharField('书名', max_length=50)
publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)
[root@vm mysite5]# python3 manage.py makemigrations
[root@vm mysite5]# python3 manage.py migrate
> desc otm_publisher;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(50) | NO | UNI | NULL | |
+-------+-------------+------+-----+---------+----------------+
desc otm_book;
+--------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| title | varchar(50) | NO | | NULL | |
| publisher_id | int(11) | NO | MUL | NULL | |
+--------------+-------------+------+-----+---------+----------------+
#先创建 '一' ,再创建 '多'
from otm.models import *
pub1 = Publisher.objects.create(name='清华大学出版社')
#用对象关联
Book.objects.create(title='python', publisher=pub1)
#用主键关联
Book.objects.create(title='Java', publisher_id=1)
#高级创建 - 利用 反向属性
pub2 = Publisher.objects.create(name='北京大学出版社')
pub2.book_set.create(title='西游记')
> select * from otm_publisher;
+----+-----------------------+
| id | name |
+----+-----------------------+
| 2 | 北京大学出版社 |
| 1 | 清华大学出版社 |
+----+-----------------------+
> select * from otm_book;
+----+--------------+--------------+
| id | title | publisher_id |
+----+--------------+--------------+
| 1 | python | 1 |
| 2 | Java | 1 |
| 3 | 西游记 | 2 |
| 4 | 红楼梦 | 2 |
| 5 | 三国演义 | 2 |
+----+--------------+--------------+
通过 Book 查询 Publisher【正向】
通过 publisher 属性查询即可 book.publisher
>>> Book.objects.get(title='java').publisher.name
'清华大学出版社'
abook = Book.objects.get(id=1)
print(abook.title, '的出版社是:', abook.publisher.name)
通过 Publisher 查询 对应的所有的 Book 【反向】
Django会在Publisher中增加一个属性来表示对对应的Book们的查询引用
属性:book_set 等价于 objects
# 通过出版社查询对应的书
pub1 = Publisher.objects.get(name='清华大学出版社')
books = pub1.book_set.all() # 通过book_set 获取pub1对应的多个Book数据对象
#books = Book.objects.filter(publisher=pub1) # 也可以采用此方式获取
print("清华大学出版社的书有:")
for book in books:
print(book.title)
多对多表达对象之间多对多复杂关系,不用指定on_delete,语法:在关联的两个类中的任意一个类中,增加:
属性 = models.ManyToManyField(MyModel)
一个作者可以出版多本图书,一本图书可以被多名作者同时编写
[root@vm mysite5]# python3 manage.py startapp mtm
[root@vm mysite5]# vim mysite5/settings.py
INSTALLED_APPS = [
...
'mtm',
[root@vm mysite5]# vim mtm/models.py
class Author(models.Model):
name = models.CharField('作家', max_length=50)
class Book(models.Model):
title = models.CharField('书名', max_length=50)
authors = models.ManyToManyField(Author)
[root@vm mysite5]# python3 manage.py makemigrations
[root@vm mysite5]# python3 manage.py migrate
> desc mtm_author;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(50) | NO | | NULL | |
+-------+-------------+------+-----+---------+----------------+
> desc mtm_book;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| title | varchar(50) | NO | | NULL | |
+-------+-------------+------+-----+---------+----------------+
> desc mtm_book_authors;
+-----------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| book_id | int(11) | NO | MUL | NULL | |
| author_id | int(11) | NO | MUL | NULL | |
+-----------+---------+------+-----+---------+----------------+
from mtm.models import *
# 方案1 先创建 author 再关联 book
author1 = Author.objects.create(name='吕老师')
author2 = Author.objects.create(name='王老师')
# 关联图书
book11 = author1.book_set.create(title="Python")
author2.book_set.add(book11)
> select * from mtm_author;
+----+-----------+
| id | name |
+----+-----------+
| 1 | 吕老师 |
| 2 | 王老师 |
+----+-----------+
2 rows in set (0.00 sec)
> select * from mtm_book;
+----+--------+
| id | title |
+----+--------+
| 1 | Python |
+----+--------+
1 row in set (0.00 sec)
> select * from mtm_book_authors;
+----+---------+-----------+
| id | book_id | author_id |
+----+---------+-----------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
+----+---------+-----------+
方案2 先创建 book 再关联 author
book = Book.objects.create(title='java')
author3 = book.authors.create(name='李老师')
book.authors.add(author1)
from mtm.models import *
>>> b1 = Book.objects.get(title='java')
>>> authors = b1.authors.all()
>>> for a in authors:
... print(a.name)
...
王老师
author1 = Author.objects.get(name='吕老师')
book.authors.all() -> 获取 book 对应的所有的author的信息
book.authors.filter(age__gt=80) -> 获取book对应的作者中年龄大于80岁的作者的信息
Django会生成一个反向属性 book_set 用于表示对对应的book的查询对象相关操作
>>> author1 = Author.objects.get(name='吕老师')
>>> books=author1.book_set.all() # author1.book_set.filter()
>>> for book in books:
... print(book.title)
...
Python
一对一
属性 = models.OneToOneField(A, on_delete=xxx)
1. 生成表结构
2. 添加数据
3. 查询数据
3.1 正向查询
3.2 反向查询
一对多【使用最多】
属性 = models.ForeignKey("一"的模型类, on_delete=xx)
1. 生成表结构
2. 添加数据
多对多【难度最大】
属性 = models.ManyToManyField(MyModel)
[root@vm mysite5]# python3 manage.py createsuperuser
用户名 (leave blank to use 'root'): tarena
[root@vm mysite5]# vim mtm/admin.py
from django.contrib import admin
from .models import *
# Register your models here.
class AuthorManager(admin.ModelAdmin):
list_display = ['id','name']
list_display_links = ['id','name']
class BookManager(admin.ModelAdmin):
list_display = ['id','title']
admin.site.register(Author,AuthorManager)
admin.site.register(Book,BookManager)
#__str__重写,不重写 django的web界面显示的是object对象,没可读写
[root@vm mysite5]# vim mtm/models.py
class Author(models.Model):
name = models.CharField('作家', max_length=50)
def __str__(self):
return self.name
class Book(models.Model):
title = models.CharField('书名', max_length=50)
authors = models.ManyToManyField(Author)
def __str__(self):
return self.title
#浏览器访问,体验功能管理
会话 - 从打开浏览器访问一个网站,到关闭浏览器结束此次访问,称之为一次会话。HTTP协议是无状态的,导致会话状态难以保持。Cookies和Session就是为了保持会话状态而诞生的两个存储技术
#新建项目,初始化配置
[root@vm ~]# mysql -uroot -p123456 -e 'create database mysite6 default charset utf8;'
[root@vm ~]# django-admin startproject mysite6
[root@vm ~]# cd mysite6/
[root@vm mysite6]# vim mysite6/settings.py
ALLOWED_HOSTS = ['*',]
DATABASES = {
'default' : {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mysite6',
'USER': 'root',
'PASSWORD': '123456',
'HOST': '127.0.0.1',
'PORT': 3306,
}
}
LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = "Asia/Shanghai"
[root@vm mysite6]# python3 manage.py runserver 0.0.0.0:8000
查看和操作浏览器端所有的 Cookies 值
Chrome 浏览器 可能通过开发者工具的Application >>Storage >>Cookies
火狐浏览器 可能通过开发者工具的 存储 -> Cookie
cookies是"保存在客户端"浏览器上的存储空间,
cookies 在浏览器上是以键-值对的形式进行存储的,键和值都是"以ASCII字符串"的形存储
cookies中的数据是"按域"存储隔离的,不同的域之间无法访问
cookies 每次访问此网址时都会携带到服务器端,如果"cookies过大会降低响应速度"
cookies 不要存储敏感的信息,不安全,(存储sessionid,相对安全)
在Django 设置浏览器的COOKIE 必须通过 HttpResponse 对象来完成
添加、修改COOKIE
HttpResponse.set_cookie(key, value='', max_age=None, expires=None)
- key:cookie的名字
- value:cookie的值
- max_age:cookie存活时间,秒为单位
- expires:具体过期时间
- 当不指定max_age和expires 时,关闭浏览器时此数据失效
删除COOKIE
- HttpResponse.delete_cookie(key)
- 删除指定的key 的Cookie。 如果key 不存在则什么也不发生。
获取cookie
通过 request.COOKIES 绑定的字典(dict) 获取客户端的 COOKIES数据
value = request.COOKIES.get('cookies名', '默认值')
print("cookies名 = ", value)
使用示例
[root@vm mysite6]# vim mysite6/urls.py
urlpatterns = [
...
path('set_cookie',views.set_cookie),
]
[root@vm mysite6]# vim mysite6/views.py
from django.http import HttpResponse
def set_cookie(request):
resp = HttpResponse("set cookie ok!")
resp.set_cookie('username','tarena',60)
return resp
访问 http://192.168.1.11:8000/set_cookie
#开发者工具 查看cookie username的键值对儿
Application >>Storage >>Cookies>>http://192.168.1.11:8000
#开发者工具 查看响应头
Network >>set_cookie >> Response Header >> Set-Cookie:
Set-Cookie: username=tarena; expires=Sun, ... GMT; Max-Age=60; Path=/
[root@vm mysite6]# vim mysite6/urls.py
path('get_cookie',views.get_cookie),
[root@vm mysite6]# vim mysite6/views.py
...
def get_cookie(request):
name = request.COOKIES.get('username', 'no-value')
return HttpResponse("cookie value is %s" % name)
访问 http://192.168.1.11:8000/get_cookie
#开发者工具 请求头
Network >>get_cookie >> resquest Header >> 没有cookie(已过期)
刷新http://192.168.1.11:8000/set_cookie
再次访问 http://192.168.1.11:8000/get_cookie 页面显示:cookie value is tarena
Network >>get_cookie >> resquest Header >> Cookie: 末尾有username=tarena
[root@vm mysite6]# vim mysite6/urls.py
path('del_cookie',views.del_cookie),
[root@vm mysite6]# vim mysite6/views.py
def del_cookie(request):
resp = HttpResponse("del cookie ok!")
resp.delete_cookie('username')
return resp
访问 http://192.168.1.11:8000/del_cookie
Network >>set_cookie >> Response Header >> Set-Cookie:
Set-Cookie: username=""; expires=Thu, 01 Jan 1970 00:00:00 GMT; Max-Age=0; Path=/
#注意 expires有效时间 Max-Age存活时间
session又名会话控制,是在服务器上开辟一段空间用于保留浏览器和服务器交互时的重要数据,实现方式
- 使用 session 需要在浏览器客户端启动 cookie,且用在cookie中存储sessionid
- 每个客户端都可以在服务器端有一个独立的Session
- 注意:不同的请求者之间不会共享这个数据,与请求者一一对应
cookies 的特点
1>保存在客户端浏览器
2>按域隔离
3>键值对存储
4>不安全,不要保存敏感数据
session的特点
1>保存在服务器
2>session的使用需要借助于cookie来存储sessionid
3>相对安全,但是也不要存储敏感数据
虽然session的原理和步骤都比cookie更复杂,但是在Django中
使用时,由于做了相应的处理,反而使用更简单。会使用字典就会使用session。
在 settings.py 文件中,向 INSTALLED_APPS 列表中添加:
INSTALLED_APPS = [
# 启用 sessions 应用,默认启用
'django.contrib.sessions',
]
向 MIDDLEWARE 列表中添加:
MIDDLEWARE = [
# 启用 Session 中间件,默认启用
'django.contrib.sessions.middleware.SessionMiddleware',
]
[root@vm mysite6]# python3 manage.py makemigrations
[root@vm mysite6]# python3 manage.py migrate
> show tables;
+----------------------------+
| Tables_in_mysite6 |
+----------------------------+
| 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 |
+----------------------------+
> desc django_session;
+--------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+-------+
| session_key | varchar(40) | NO | PRI | NULL | |
| session_data | longtext | NO | | NULL | |
| expire_date | datetime(6) | NO | MUL | NULL | |
+--------------+-------------+------+-----+---------+-------+
session的基本操作:
保存 session 的值到服务器
request.session['KEY'] = VALUE
获取session的值
VALUE = request.session['KEY']
VALUE = request.session.get('KEY', 缺省值)
删除session的值
del request.session['KEY']
在 settings.py 中有关 session 的设置
1. SESSION_COOKIE_AGE
- 作用: 指定sessionid在cookies中的保存时长(默认是2周),如下:
- SESSION_COOKIE_AGE = 60 * 60 * 24 * 7 * 2
2. SESSION_EXPIRE_AT_BROWSER_CLOSE = True
设置只要浏览器关闭时,session就失效(默认为False)
当使用session时需要迁移数据库,否则会出现错误
python3 manage.py migrate
[root@vm mysite6]# vim mysite6/urls.py
path('set_session',views.set_session),
path('get_session',views.get_session),
[root@vm mysite6]# vim mysite6/views.py
...
def set_session(request):
request.session['username'] = 'tarena'
return HttpResponse("set session is ok")
def get_session(request):
username = request.session.get('username', 'no-value')
return HttpResponse("user name is %s" % username)
http://192.168.1.11:8000/set_session
#开发者工具 查看cookie username的键值对儿
Application >>Storage >>Cookies>>http://192.168.1.11:8000
sessionid: kim2qi8v4lcfy92ax9r7gn6r4c4zkj0v
#开发者工具 查看响应头
Set-Cookie: sessionid=kim2qi8v4lcfy92ax9r7gn6r4c4zkj0v
这与数据库里存储的session_key是同一个
> select * from django_session\G
*************************** 1. row ***************************
session_key: kim2qi8v4lcfy92ax9r7gn6r4c4zkj0v
session_data: YjFkZjBiZmQ4MzFhZDIwZWI0YWZhNDMxOTE5ZDE0Nj...
...
http://192.168.1.11:8000/get_session
user name is tarena
[root@vm mysite6]# vim mysite6/urls.py
path('del_session',views.del_session),
[root@vm mysite6]# vim mysite6/views.py
def del_session(request):
if 'username' in request.session:
del request.session['username']
return HttpResponse("del session is ok")
[root@vm mysite6]# vim mysite6/settings.py
SESSION_COOKIE_AGE = 60
http://192.168.1.11:8000/set_session 看响应头Max-Age=60
django 原生session 问题:
1,django_session表是 单表设计;且该表数据量持续增持,不会删除包括
恶意删除的sessionid(客户端手动删掉sessionid,重新请求服务器生成新的)
过期的sessionid数据
2,可以每晚执行 python3 manage.py clearsessions可删除已过期的session数据
恶意删除的sessionid,未过期,命令无法删除