自学python 进击之路 - Django-关系映射

148 阅读7分钟

src=http___5b0988e595225.cdn.sohucs.com_images_20190916_32ce26032b124c3cb145a4231627373d.jpeg&refer=http___5b0988e595225.cdn.sohucs.jpg

admin后台管理-1

什么是admin管理后台

  • django 提供了比较完善得到后台管理数据库的接口,可供开发过程中调用和测试使用、
  • django 会搜集所有已注册的模型类,为了这些模型类提供数据管理界面,供开发者使用

admin配置步骤

  • 创建后台管理账号-该账号为管理后台最高权限账号

python3 manage.py createsuperuser

$ python3 manage.py createsuperuser
Username (leave blank to use 'xxx'): xxx # 此处输入用户名
Email address: 12346@163.com # 此处输入邮箱
Password: # 此处输入密码(密码要复杂些,否则会提示密码简单了)
Password(again): # 再次输入重复密码
Superuser created successfully.

admin后台管理-2

注册自定义模型类

若有自己定义的模型类也能在/admin 后台管理界中显示和管理。需要将自己的类注册到后台管理界面

注册步骤:

  1. 在应用app中的admin中的admin.py 中导入注册要管理的模型models类
from .models import Book
  1. 调用admin.site.register 方法进行注册。
admin.site.register(自定义模型类)

模型管理类

  • 作用:为了后台管理界面添加便于操作的新功能
  • 说明: 后台管理器类须继承自django.contrib.admin 里的ModelAdmin类

使用方法:

  1. 在<应用app>/admin.py 里定义模型管理器类
class xxxxManager(admin.ModelAdmin):
.....
  1. 绑定注册模型管理器和模型类
from django.contrib import admin
from .models import *
admin.site.register(YYYY, XXXXManager) # 绑定 YYYY 模型类与管理器类 XXXXManager
  1. 案例
# 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)
  1. 更多的模型类

Snipaste_2021-07-21_20-34-58.png 5. 最终效果

Snipaste_2021-07-21_20-36-21.png

再谈Meta类

  • 通过Meta内嵌类 定义模型类的属性, 用法如下:
class Book(models.model):
   title = CharField(....)
   class Meta:
     1. db_tadle = '数据表名'
         — 该模型所在的数据表的名称(设置完成后需要立马更新同步数据库)
     2. verbose_name = '单数名'
         - 给模型对象的一个易于理解的名称(单数), 用于显示在/admin管理界面中
     3. verbose_name_plural = '复数名'
         - 该对象复数形式的名称(复数), 用于显示在/admin 管理界面

关系映射

什么是关系关系映射

  • 关系型数据库中,通常不会把所有数据都放在同一张表中。不易于扩展,常见关系映射有:
  1. 一对一映射 2.一对多映射 3.多对多映射

一对一【创建】

  • 一对一时表示现实事物间存在的一对一的对应关系
  • 如:一个家庭只有一个户主,一个男人有一个妻子,一个人有一个唯一的指纹信息等
  • 语法:OneToOneField(类名。 on_delete=xxxx)
class A(model.Model):
    ....
class B(molde.Model):
     属性 = models.OneToOneField(A, on_delete=xxxx)
  • 特殊字段选项【必须】
  • on_dalete- 级联删除 1.models.CASCADE 级联删除,Djiaog模拟Sql结束ON DELETE CASCADE 的行为, 并删除包含ForeignKey的对象
  1. models.PROTECT抛出ProtectedError 以阻止被引用对象的删除;[等同于mysql默认的RESTRICT]
  2. SET_NULL设置ForeignKey null ; 需要指定null = True
  3. SET_DEFAULT 将Foreignkey 设置为其默认值;必须设置Foreignkey的默认值
  • 示例- 创建模型类 - oto/models.py
from django.db import models

class Author(models.Model):
'''作家模型类'''
       name = models.charField('作家', max_length=50)
      
      
class wife(models.Model):
   ''' 作家妻子模型类'''
       name = models.charField('妻子', max_length=50 )
       author = models.OneToOneField(Author, on_delese= models.CASCADE)  # 正增加一对一属性
  • 无外键的模型类[Author]:
author1 = Author.objects.create(name = ' 王老师')
  • 有外键的模型类[Wife]
 wife1  = Wife.objects.create(name='王夫人', author = author1) #关联王老师 obj
   wife1  = Wife.objects.create(name='王夫人', author = author_id = 1) #关联王老师 obj

一对一【查询数据】

  1. 正向查询:直接通关外键属性查询,则称为正向查询
# 通过wife 找author
from .models import wife
wife = Wife.objects.get(name= ' 王夫人')
print(wife.name ,  '的老公是', wife.author.name)
  1. 反向查询-没有外键属性的一方,可以调用反向属性查询到关联的另一方反向关联属性为'示例对象'.引用类名(小写),如作家的反向引用为作家对象.wife
  • 当反向引用不存在时, 则会触发异常
author1 = Author.objects.get(name= '王老师')

author1.wife.name

一对多

  • 语法:
# 当一个A类对象可以关联多个B类对象时
class A(model.Model):
     . . . 
class B(model.Model):
    属性 = model.Foreignkey('一'的模型类, on_delete=xx)
 # ForeignKey必须指定on_delete模式
  • 示例 - 创建模型类- otm/models.py
#file:otm/models.py
from django.db import models

class Publisher(models.Model):
     '''出版社'''
     name = modelsCharField('名称', max_length=50, unique=True)
     
class Book(models.Model):
      '''书'''
      title = models.CharField('书名', max_length=50)
      publisher = ForeignKey(publisher, on_delete = models.CASCADE)

一对多-创建数据

  • 先创建‘一’在创建‘多’
 
Book.objects.create(title= 'Java', publisher_id=1)

查询数据

  1. 正向查询[通过Book查询Publisher]
通过publisher 属性查询即可
book.publisher

abook = Book.objects.get(id=1)
print(abook.title, '的出版社是:', abook.publisher.name)
  1. 方向查询[通过Publisher 查询对应的所有的Book]
# 需要反向属性
# 通过出版社查询对应的书
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)

多对多-创建数据

  • 用法示例
    • 一个作者可以出版多本图书
    • 一本图书可以被多名作者同时编写
class Author(models.Model):
    . . . 
 class Book(models.Model):
       ...
       authotrs = models.ManyToManyField(Author)

方案1 先创建author 再关联book
 author1 = Author.objects.create(name='吕老师')
 author2 = Author.objects.create(name='吕老师')
 # 吕老师和王老师同时写了一本python
 book11 = author1.book_set.create(title='python')
 author2.book_set.add(book11)
方案2 先创建book 再关联 author
book = Book.objects.create(title= 'python1')
author3 = book.authors.create(name='haonanren')
book.authors.add(author1)

cookies和session

会话

定义

  • 从打开浏览器访问一个网站,到关闭浏览器结束此次访问,称为一次会话
  • HTTP协议是无状态的,导致会话状态难以保持
  • Cookies和Session就是为了保持会话状态而诞生的两个存储技术

Cookies

定义

cookies 是保存在客户端浏览器上的存储空间
     - Chrome 浏览器可能通过开发者工具的Application>>Storage>>	`Cookies` 查看和操作浏览器所有的Cookies值
     - 火狐浏览器 可通过开发者工具的存储--> Cookies查看

Cookies特点

-   cookies在浏览器上是以键-值对的形式进行存储的, 键和值都是以ASCll 字符串的形式存储(不能是中文字符串)
-   存储的数据带有生命周期
-   cookies中的数据是按域存储隔离的,不同的域之间无法访问
-   cookies的内部的数据会在每次访问此网址时都会携带到服务器端,如果cookies过大会减低响应速度

Cookies的使用-存储

HttpRequest.set_cookie(key, value='', max_age=None, expires=None)
- key:cookie的名字
- value:cookie的值
- max_age:cookie存活时间,秒为单位
- expires:具体过期时间
- 当不指定max_age和expire时,关闭浏览器时此数据失效

存储示例:

  • 添加cookie
# 为浏览器添加键为my_var1,修改值为456,过期时间为2个小时的cookie
responds = HttpResponse('已修改my_var1, 值为456')
responds.set_cookie('my_var', 456, 3600*2)
return responds
  • 修改cookie
# 为浏览器添加键为my_var1,修改值为456,过期时间为2个小时的cookie
responds = HttpResponse('已修改my_var1, 值为456')
responds.set_cookie('my_var', 456, 3600*2)
return responds

Cookies的使用-删除&获取

  • 删除Cookies
- HttpRequest.delete_cookie(key)
- 删除指定的key的Cookie 如果key不存在则什么也不发生
案例:
# 删除浏览器键为my_var1的cookie
responds = HttpResponse('已删除 my_var1')
responds.delete_cookie('my_var1')
return responds
  • 获取Cookies
- 通过requset.COOKIES 绑定的字典(dict)获取客户端的COOKIES数据
value = requset.COOKIES.get('cookies名','默认值')
# 获取浏览器中my_var1变量对应的值
value = request.COOKIES.get('my_var1', '没有值')
print('cookie my_var1 = ' , value)
return HttpResponse('my_var1:'+ value)

session定义

  • session是在服务器上开辟一段时间用于保留浏览器和服务器交互时的重要数据
  • 实现方式
- 使用session需要在浏览器客户端启动cookie, 且在cookie中存储sessionid
- 每个客户端都可以在服务器端有一个独立的Session
- 注意:不同的请求者之间不会共享这个数据,与请求者一一对应

session 初始配置

  • setting.py中配置session向INSTALLED_APPS列表中添加:

Snipaste_2021-07-22_21-18-29.png

向MIDDLEWARE列表中添加

Snipaste_2021-07-22_21-19-59.png

session的使用

  • ssion对于是一个类别与字典的SessionStore类型的对象,可以用类拟于字典的方式进行操作
  • session能够存储如字符串,整形,字典,列表等
1保存session的值到服务器
request.session['KEY'] = value
2.获取session的值
value = request.session['KEY']
value = request.session.get('KEY',  默认值)
3.删除session
del request.session['KEY']
  • settings.py中相关配置项
1.SESSION_COOKIE_AGE
作用:指定sessionid在cookies中的保存时长(默认是两周),如下:
例:SESSION_COOKIE_AGE = 60 * 60 * 24 * 7 *2
2.SESSION_EXPIRE_AT_BROWSER_CLOSE =True
设置只要浏览器关闭时,session就失效(默认为False)
注意:Django中的session数据存储在数据库中,所以使用session前需要确保已经执行migrate

Django session 的问题

  1. django_session表示单表设计;且该表数据量持续增持【浏览器故意删掉session& 过期数据未删除】
  2. 可以每晚执行python3 manage.py clearsessions【该命令可删除一过期的session数据】