pt26django教程

admin 后台数据库管理

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: 1password: pbkdf2_sha256$150000$yE0lYzKHcN9i$VShFRN+WFSWd4qOuZDdnEJIi0j0b3u2XHZMJMuQuPvQ=last_login: NULL
is_superuser: 1username: tarenafirst_name:last_name:email: 123456@qq.comis_staff: 1is_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)  #注册

使用预览(功能还不是很完善需改造)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

修改自定义模型类的展现样式

  • 在admin后台管理数据库中对自定义的数据记录都展示为 XXXX object 类型的记录,不便于阅读和判断
  • 在用户自定义的模型类中可以重写 def __str__(self): 方法解决显示问题,如:
    • 在 自定义模型类中重写 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 Bookclass BookManager(admin.ModelAdmin):list_display = ['id', 'title', 'price', 'market_price']admin.site.register(Book, BookManager)

进入http://127.0.0.1:8000/admin/bookstore/book/ 查看显示方式和以前有所不同
在这里插入图片描述

  • 模型管理器类ModelAdmin中实现的高级管理功能
    1. list_display 去控制哪些字段会显示在Admin 的修改列表页面中。
    2. list_display_links 可以控制list_display中的字段是否应该链接到对象的“更改”页面。
    3. list_filter 设置激活Admin 修改列表页面右侧栏中的过滤器
    4. search_fields 设置启用Admin 更改列表页面上的搜索框。
    5. list_editable 设置为模型上的字段名称列表,这将允许在更改列表页面上进行编辑。
    6. 其它参见https://docs.djangoproject.com/en/2.2/ref/contrib/admin/
# file : bookstore/admin.py
from django.contrib import admin
from .models import Bookclass 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)

再谈Meta类

模型类可以通过定义内部类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.pyALLOWED_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

常用的表关联方式有三种:

  1. 一对一映射:如: 一个身份证对应一个人
  2. 一对多映射:如: 一个班级可以有多个学生
  3. 多对多映射:如: 一个学生可以报多个课程,一个课程可以有多个学生学习

一对一映射OneToOneField

语法

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=Truemodels.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.pyfrom django.db import modelsclass 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 shellfrom 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 |
+----+-----------+-----------+

数据查询

  1. 正向查询:直接通过关联属性查询即可

    # 通过 wife 找 author 
    from oto.models import Wife
    wife = Wife.objects.get(name='王夫人')
    print(wife.name, '的老公是', wife.author.name)#王夫人 的老公是 王老师
    
  2. 反向查询

    • 通过反向关联属性查询
    • 反向关联属性为实例对象.引用类名(小写),如作家的反向引用为作家对象.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, '还没有妻子')#小李老师 还没有妻子 
    

一对多映射ForeignKey

一对多是表示现实事物间存在的一对多的对应关系。语法:当一个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 modelsclass Publisher(models.Model):# 有一个反向属性,book_setname = 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)

多对多映射ManyToManyField

多对多表达对象之间多对多复杂关系,不用指定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 再关联 bookauthor1 = 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)

数据查询

  1. 通过 Book 查询对应的所有的 Author【正向】
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岁的作者的信息
  1. 通过 Author 查询对应的所有的Book【反向】

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)

添加到djanto管理界面

[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.nameclass Book(models.Model):title = models.CharField('书名', max_length=50)authors = models.ManyToManyField(Author)def __str__(self):return self.title#浏览器访问,体验功能管理  		

cookies 和 session

会话 - 从打开浏览器访问一个网站,到关闭浏览器结束此次访问,称之为一次会话。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.pyALLOWED_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

查看和操作浏览器端所有的 Cookies 值Chrome 浏览器 可能通过开发者工具的Application >>Storage >>Cookies火狐浏览器 可能通过开发者工具的 存储 -> Cookie
cookies是"保存在客户端"浏览器上的存储空间,cookies 在浏览器上是以键-值对的形式进行存储的,键和值都是"以ASCII字符串"的形存储cookies中的数据是"按域"存储隔离的,不同的域之间无法访问cookies 每次访问此网址时都会携带到服务器端,如果"cookies过大会降低响应速度"cookies  不要存储敏感的信息,不安全,(存储sessionid,相对安全)

Django 设置COOKIE

在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)
    

使用示例

添加cookie

[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 HttpResponsedef 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=/

获取cookie

[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 tarenaNetwork >>get_cookie >> resquest Header >> Cookie: 末尾有username=tarena

删除cookie

[root@vm mysite6]# vim mysite6/urls.py  path('del_cookie',views.del_cookie),[root@vm mysite6]# vim mysite6/views.pydef 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又名会话控制,是在服务器上开辟一段空间用于保留浏览器和服务器交互时的重要数据,实现方式

- 使用 session 需要在浏览器客户端启动 cookie,且用在cookie中存储sessionid
- 每个客户端都可以在服务器端有一个独立的Session
- 注意:不同的请求者之间不会共享这个数据,与请求者一一对应
cookies 的特点1>保存在客户端浏览器2>按域隔离3>键值对存储4>不安全,不要保存敏感数据
session的特点1>保存在服务器2>session的使用需要借助于cookie来存储sessionid3>相对安全,但是也不要存储敏感数据     虽然session的原理和步骤都比cookie更复杂,但是在Django中使用时,由于做了相应的处理,反而使用更简单。会使用字典就会使用session。

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对于象是一个类似于字典的SessionStore类型的对象, 可以用类拟于字典的方式进行操作
  • 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 * 22. SESSION_EXPIRE_AT_BROWSER_CLOSE = True设置只要浏览器关闭时,session就失效(默认为False)  当使用session时需要迁移数据库,否则会出现错误python3 manage.py migrate

session添加

[root@vm mysite6]# vim mysite6/urls.pypath('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

session删除

[root@vm mysite6]# vim mysite6/urls.pypath('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")

设置session 时间

[root@vm mysite6]# vim mysite6/settings.py
SESSION_COOKIE_AGE = 60http://192.168.1.11:8000/set_session     看响应头Max-Age=60

删除已过期session

django 原生session 问题:

1,django_session表是 单表设计;且该表数据量持续增持,不会删除包括恶意删除的sessionid(客户端手动删掉sessionid,重新请求服务器生成新的)过期的sessionid数据
2,可以每晚执行 python3 manage.py clearsessions可删除已过期的session数据恶意删除的sessionid,未过期,命令无法删除

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/80876.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode 753. 破解保险箱【欧拉回路,DFS】困难

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

在标准的C++ 语法中,请问有 MyCppClass* mycppclass 这样的变量定义方式吗?

在标准的C 语法中&#xff0c;请问有 MyCppClass*& mycppclass 这样的变量定义方式吗&#xff1f; Author: Lycan Date: 2023/9/16 11:53 Note: 以下问题解答通过大模型生成&#xff0c;主要用于个人学习和备忘&#xff0c;仅供参考&#xff0c;若有错误或者侵权&#xff…

如何从第一性原则的原理分解数学问题

如何从第一性原则的原理分解数学问题 摘要&#xff1a;牛津大学入学考试题目展示了所有优秀数学家都使用的系统的第一原则推理&#xff0c;而GPT4仍然在这方面有困难 作者&#xff1a;Keith McNulty 我们中的许多人都熟悉直角三角形的边的规则。根据毕达哥拉斯定理&#xff0c;…

2023年墨西哥 SP/BMV IPC 研究报告

第一章 指数概况 1.1 指数基本情况 墨西哥 S&P/BMV IPC 指数衡量在墨西哥证券交易所 (Bolsa Mexicana de Valores, BMV)上市&#xff0c;规模最大、流动性最高的股票表现。提供一个覆盖墨西哥股市的广泛、具有代表性且可轻易复制的指数。根据多元化要求&#xff0c;按市值…

【深度学习】 Python 和 NumPy 系列教程(廿五):Matplotlib详解:3、多子图和布局:subplot()函数

目录 一、前言 二、实验环境 三、Matplotlib详解 1、2d绘图类型 2、3d绘图类型 3、多子图和布局 1. subplot()函数 简单示例 一、前言 Python是一种高级编程语言&#xff0c;由Guido van Rossum于1991年创建。它以简洁、易读的语法而闻名&#xff0c;并且具有强大的功能…

使用Selenium和Python自动预订车票

在本文中&#xff0c;我们将探讨如何使用Selenium和Python自动预订车票。我们将以12306.cn网站为例&#xff0c;演示自动化预订车票的过程。通过阅读本文&#xff0c;您将更好地了解如何使用Selenium与网页进行交互。 准备工作 首先&#xff0c;我们需要安装Selenium库。您可…

多表查询——“MySQL数据库”

各位CSDN的uu们好呀&#xff0c;今天&#xff0c;小雅兰的内容是MySQL数据库中的多表查询啦&#xff0c;这个内容确实是一个难点&#xff0c;下面&#xff0c;让我们进入多表查询的世界吧&#xff01;&#xff01;&#xff01; 一个案例引发的多表连接 多表查询分类讲解 SQL9…

bootstrap table export的使用,bootstrap table表格前端导出

第一步&#xff1a;html页面导入2个JS文件 1.依赖文件tableExport.js&#xff0c;该文件的内容如下&#xff1a; use strict;(function ($) {$.fn.tableExport function (options) {let docData;const defaults {csvEnclosure: ",csvSeparator: ,,csvUseBOM: true,dat…

vue前端拿到后端pdf与zip等重新打包为一个新的zip包

目录 vue前端拿到后端pdf与zip等重新打包为一个新的zip包code.vue vue前端拿到后端pdf与zip等重新打包为一个新的zip包 code.vue const urlList [{fileUrl:https://XX.zip,fileName:我是文件.zip},{fileUrl:https://XXX.pdf,fileName:我是pdf.pdf}]this.downloadZip(urlList)…

精品SpringCloud的高校招生信息管理系统-微服务分布式

《[含文档PPT源码等]精品基于SpringCloud实现的高校招生信息管理系统-微服务-分布式》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程等 软件开发环境及开发工具&#xff1a; 开发语言&#xff1a;Java 框架&#xff1a;springcloud JDK版本&#x…

FL Studio v21.1.1.3750 Producer Edition inc crack官方中文免费激活版功能介绍及百度网盘下载

FL Studio v21.1.1.3750 Producer Edition inc crack官方中文免费激活版是一款功能强大的软件音乐制作环境或数字音频工作站&#xff08;DAW&#xff09;。它代表了25多年的创新发展&#xff0c;在一个软件包中拥有您所需的一切&#xff0c;以创作、编排、录制、编辑、混音和掌…

Python--测试代码

目录 1、使用pip安装pytest 1.1 更新pip 1.2 安装putest 2、测试函数 2.1 单元测试和测试用例 2.2 可通过的测试 2.3 运行测试 2.4 未通过的测试 2.5 解决测试未通过 2.6 添加新测试 3、测试类 3.1 各种断言 3.2 一个测试的类 3.3 测试AnonymousSurvey类 3.4 使…

Linux命令200例:dip用于用户与远程主机建立通信连接

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;CSDN领军人物&#xff0c;全栈领域优质创作者✌。CSDN专家博主&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0…

主题教育活动知识竞赛小程序界面分享

主题教育活动知识竞赛小程序界面分享

数据结构:数组

文章目录 数组一&#xff0c;概述二&#xff0c;添加数据三&#xff0c;删除数据 数组 一&#xff0c;概述 数组是一种线性表数据结构&#xff0c;它用一组连续的内存空间来存储一组具有相同类型的数据。 数组可以被视为一块连续的内存&#xff0c;即使物理上不连续&#xf…

微服务保护-授权规则

个人名片&#xff1a; 博主&#xff1a;酒徒ᝰ. 个人简介&#xff1a;沉醉在酒中&#xff0c;借着一股酒劲&#xff0c;去拼搏一个未来。 本篇励志&#xff1a;三人行&#xff0c;必有我师焉。 本项目基于B站黑马程序员Java《SpringCloud微服务技术栈》&#xff0c;SpringCloud…

lighttpd以及socket和WebSocket编程

综述 本文涉及到下图绿色背景部分的内容&#xff1a; 左侧位于Linux下&#xff0c;其中包括lighttpd和socket程序&#xff1b;右侧是WebSocket程序。两者通过网络交互。 本文介绍lighttpd的基本使用方式&#xff0c;并通过编程完成一个socket服务器与浏览器端的WebSocket客户…

本地docker注册证书docker login连接到harbor仓库、利用shell脚本将大量镜像pull、tag、push到私有harbor仓库

1. 本地docker注册证书docker login连接到harbor仓库&#xff1a; 我们使用docker login/push/pull去与Harbor打交道&#xff0c;上传下载镜像等。 但是可能会出现x509: certificate signed by unknown authority之类的错误。 [roottest01 harbor.dev]# docker login harbor.d…

递归算法实现二分查找c++

递归算法可以用来实现二分查找。二分查找是一种高效的搜索算法&#xff0c;适用于已排序的数组。下面是使用递归算法实现二分查找的示例代码&#xff1a; #include <iostream> using namespace std;// 递归二分查找函数 int binarySearch(int arr[], int low, int high,…

数学建模__动态规划

动态规划就是&#xff0c;将任务每一步均记录下来&#xff0c;以便将来重复使用时能够直接调用 问题描述&#xff1a;给定n个物品&#xff0c;每个物品的重量是Wi,价值是Vi&#xff0c;但是背包最多能装下capacity重量的物品&#xff0c;问我们如何选择才能利益最大化。 这里涉…