pt26django教程

news2025/1/16 1:46:42

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: 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)  #注册

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

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

  • 在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 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/ 查看显示方式和以前有所不同
在这里插入图片描述

  • 模型管理器类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 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)

再谈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.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

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

  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=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 |
+----+-----------+-----------+

数据查询

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

多对多映射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 再关联 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)

数据查询

  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.name
    
class 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.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

查看和操作浏览器端所有的 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 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=/

获取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 tarena

Network >>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.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又名会话控制,是在服务器上开辟一段空间用于保留浏览器和服务器交互时的重要数据,实现方式

- 使用 session 需要在浏览器客户端启动 cookie,且用在cookie中存储sessionid
- 每个客户端都可以在服务器端有一个独立的Session
- 注意:不同的请求者之间不会共享这个数据,与请求者一一对应
cookies 的特点
      1>保存在客户端浏览器
      2>按域隔离
      3>键值对存储
      4>不安全,不要保存敏感数据
session的特点
      1>保存在服务器
      2>session的使用需要借助于cookie来存储sessionid
      3>相对安全,但是也不要存储敏感数据     
   虽然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 * 2
  2. SESSION_EXPIRE_AT_BROWSER_CLOSE = True
     设置只要浏览器关闭时,session就失效(默认为False)  

当使用session时需要迁移数据库,否则会出现错误
	python3 manage.py migrate

session添加

[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

session删除

[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")

设置session 时间

[root@vm mysite6]# vim mysite6/settings.py
SESSION_COOKIE_AGE = 60

http://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.coloradmin.cn/o/1016476.html

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

相关文章

什么是函数重载?作用是什么?如何使用?

函数重载是指在同一个作用域内&#xff0c;允许存在多个同名函数&#xff0c;但这些函数的参数列表必须不同。根据传入的参数类型、数量或顺序的不同&#xff0c;编译器可以区分调用哪个函数。 函数重载的作用主要有以下几点&#xff1a; 提高代码的可读性和可维护性&#xff…

openlayers-17-卷帘对比

实现卷帘对比功能&#xff0c;没有进一步测试版本兼容问题&#xff0c;不错从ol的官网来看&#xff0c;ol6之前的版本的示例与ol6及其之后的版本示例并不相同 ol5 示例https://openlayers.org/en/v5.3.0/examples/layer-swipe.html?qlayerswipeol6示例 https://openlayers.org…

GIS跟踪监管系统

GIS跟踪监管系统 系统架构功能模块1. 基本功能2. 仓库管理3. 物资查询 系统采用B/S架构&#xff0c;前端使用的技术为HTMLCSSJavaScript&#xff08;Leaflet、jQuery、bootstrap等&#xff09;&#xff0c;后台采用.NET框架。 系统架构 救援物资跟踪监管系统的架构如图所示&am…

Matplotlib入门

基本使用 基本用法 import matplotlib.pyplot as plt import numpy as npxnp.linspace(-1,1,50) y2*x1plt.figure()#定义一个图像窗口 plt.plot(x,y)#画&#xff08;x&#xff0c;y&#xff09;曲线 plt.show()#显示图像figure图像 import matplotlib.pyplot as plt import …

nat的基础配置(动态nat,nat server)

目录 1.静态nat 2.动态nat &#xff08;1&#xff09;配置公网地址池 &#xff08;2&#xff09;配置acl&#xff0c;匹配做nat转换的源 &#xff08;3&#xff09;将源转换为公网地址&#xff0c;其中no-pat表示不做端口转化&#xff0c;只做一对一的地址转换 3.nat ser…

《向量数据库指南》——向量数据库Milvus Cloud为什么选择开源?

开源对我们来说是一种信仰。从最早开始研发向量数据库的时候&#xff0c;我们就相信应该让更多人了解并使用优秀的技术&#xff0c;这是我们选择做开源的原因。 无论是在 AI 领域还是其他领域&#xff0c;我们希望技术不会被少数大公司垄断。在向量数据库问世之前&#xff0c;阿…

python:优化一EXCEL统计用类封装一下

# encoding: utf-8 # 版权所有 2023 涂聚文有限公司 # 许可信息查看&#xff1a; # 描述&#xff1a; # Author : geovindu,Geovin Du 涂聚文. # IDE : PyCharm 2023.1 python 311 # Datetime : 2023/9/17 5:40 # User : geovindu # Product : PyCharm # Proj…

JSON和全局异常处理

目录 1️⃣JSON 一、什么是json&#xff1f; 二、与javascript的关系 三、语法格式 四、注意事项 五、总结 六&#xff0c;使用json 1导入pom.xml依赖 2.配置spring-mvc.xml 3. ResponseBody注解使用 创建一个web层控制器 编写ClazzBiz 实现接口 测试&#xff1a; …

C#,数值计算——Hashfn2的计算方法与源程序

1 文本格式 using System; using System.Collections; using System.Collections.Generic; namespace Legalsoft.Truffer { public class Hashfn2 { private static ulong[] hashfn_tab { get; set; } new ulong[256]; private ulong h { get; set;…

【2023年11月第四版教材】第13章《资源管理》(第三部分)

第13章《资源管理》&#xff08;第部分&#xff09; 4 管理过程4.1 数据表现★★★4.2 资源管理计划★★★4.2 团队章程★★★ 5 估算活动资源 4 管理过程 组过程输入工具和技术输出规划1.规划资源管理1.项目章程2.项目管理计划&#xff08;质量管理计划、范围基准&#xff09…

elasticsearch5-RestAPI操作

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

Python 布尔类型和比较运算符

视频版教程 Python3零基础7天入门实战视频教程 布尔( bool&#xff09;表达现实生活中的逻辑&#xff0c;即真和假&#xff0c;True表示真&#xff0c;False表示假。 实例&#xff1a; # 布尔类型定义 b1 True b2 False print(f"b1{b1},类型是{type(b1)}") prin…

分类预测 | MATLAB实现WOA-CNN-LSTM-Attention数据分类预测

分类预测 | MATLAB实现WOA-CNN-LSTM-Attention数据分类预测 目录 分类预测 | MATLAB实现WOA-CNN-LSTM-Attention数据分类预测分类效果基本描述模型描述程序设计参考资料 分类效果 基本描述 1.MATLAB实现WOA-CNN-LSTM-Attention数据分类预测&#xff0c;运行环境Matlab2021b及以…

Vue3+Ts+Vite项目(第十五篇)——tailwindcss安装及使用详解,css原子化如何实现

文章目录 一、装包二、初始化2.1 终端执行如下命令2.2 postcss.config.js 文件中2.3 tailwind.config.js 文件中 三、样式文件3.1 新建 tailwind.css 文件3.2 main.ts 中引入 四、使用4.1 写入类名即可4.2 简单讲解 五、插件5.1 安装 Tailwind CSS IntelliSense5.2 使用效果 六…

系统架构设计高级技能 · 构件与中间件技术

点击进入系列文章目录 现在的一切都是为将来的梦想编织翅膀&#xff0c;让梦想在现实中展翅高飞。 Now everything is for the future of dream weaving wings, let the dream fly in reality. 系统架构设计高级技能 构件与中间件技术 一、构件的定义二、构件系统架构特性三…

Vue ——09、路由模式,404和路由勾子

路由嵌套&#xff0c;参数传递及重定向 一、路由模式&#xff08;有#号&#xff0c;跟没#号&#xff09;二、404三、路由勾子四、在钩子函数中使用异步请求————————创作不易&#xff0c;如觉不错&#xff0c;随手点赞&#xff0c;关注&#xff0c;收藏(*&#xffe3;︶…

STM32 CubeMx教程 -- 基础知识及配置使用教程

文章目录 前言一、STM32CubeMx 界面介绍File 界面Windows 界面Help 界面Updater Settings 界面 二、STM32CubeMx 使用教程新建工程配置RCC时钟参数配置SYS参数配置时钟树Project&#xff08;工程设置&#xff09;Code Generator&#xff08;代码生成器&#xff09;工程创建 三、…

Day46:项目-购物车案例

购物车案例 准备工作 首页默认加载&#xff0c;其余页面懒加载 调用defineStore方法构建store 入口main做对应配置&#xff0c;找指南&#xff0c;快速开始&#xff0c;把elementplus引入进来 import { createApp } from "vue"; import { createPinia } from &qu…

基于香橙派和SU-03T 使用Linux实现语音控制刷抖音

硬件介绍 SU-03T之前在小车的时候使用过&#xff0c;详见&#xff1a;语音小车---6 最终整合_mjmmm的博客-CSDN博客 按照下图进行接线&#xff1a; 项目需求 通过语音指令来控制安卓手机刷抖音&#xff0c;可以实现视频切换和点赞等功能&#xff1a; 1. 开机播报“你好&a…

产品经理-战略-战略的含义和层级

引言 22年老板在听我做部门人员数量汇报时&#xff0c;当场就给我们部门员工做能力标签&#xff0c;过了几天就输出了一个公司所有技术岗位的能力标签。其中有一项是战略思维&#xff0c;该项满分是5分&#xff0c;我们部门同事绝大部分人都只有2分&#xff0c;我自己也就3…