以电商网站,例如淘宝为例:
前台:面向广大用户访问和使用.页面新颖,功能较多.例如:浏览商品,添加购物车,支付购买等.
后台:面向淘宝公司员工.功能一般是固定化的,例如:商品的管理,用户的管理等等.
/admin
后台管理界中显示和管理,需要将自己的类注册到后台管理界面admin.site.register(自定义模型类)
方法进行注册
from .models import Book
from django.contrib import admin
admin.site.register(自定义模型类)
# file: bookstore/admin.py
from django.contrib import admin
# Register your models here.
from . import models
...
admin.site.register(models.Book) # 将Book类注册为可管理页面
XXXX object
类型的记录,不便于阅读和判断def __str__(self):
方法解决显示问题,如:
class Book(models.Model):
...
def __str__(self):
return "书名" + self.title
作用:
说明:
django.contrib.admin
里的 ModelAdmin
类模型管理器的使用方法:
<应用app>/admin.py
里定义模型管理器类class XXXXManager(admin.ModelAdmin):
......
from django.contrib import admin
from .models import *
admin.site.register(YYYY, XXXXManager) # 绑定 YYYY 模型类与 管理器类 XXXXManager
# 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)
模型管理器类ModelAdmin中实现的高级管理功能
通过Meta内嵌类 定义模型类的属性
模型类可以通过定义内部类class Meta 来重新定义当前模型类和数据表的一些属性信息
用法格式如下:
class Book(models.Model):
title = CharField(....)
class Meta:
1. db_table = '数据表名'
# 该模型所用的数据表的名称。(设置完成后需要立马更新同步数据库)
2. verbose_name = '单数名'
# 给模型对象的一个易于理解的名称(单数),用于显示在/admin管理界面中
3. verbose_name_plural = '复数名'
# 该对象复数形式的名称(复数),用于显示在/admin管理界面中
- 示例:
- 将Author 模型类加入后台管理
- 制作一个AuthorManager管理器类,让后台管理Authors列表中显示作者的ID、姓名、年龄信息
- 用后台管理程序 添加三条 Author 记录
- 修改其中一条记录的年龄 - Author
- 删除最后一条添加的记录 - Author
总结:Django的后台数据管理提供了完善的**用户权限模块,**通过注册和模型管理类,还能方便的**管理自定义的模型类.**
## 数据表关联关系映射
- 常用的表关联方式有三种:
1. 一对一映射
- 如: 一个身份证对应一个人
2. 一对多映射
- 如: 一个班级可以有多个学生
3. 多对多映射
- 如: 一个学生可以报多个课程,一个课程可以有多个学生学习
### 一对一映射
- 一对一是表示现实事物间存在的一对一的对应关系。
- 如:一个家庭只有一个户主,一个男人有一个妻子,一个人有一个唯一的指纹信息等
语法
```python
class A(model.Model):
...
class B(model.Model):
属性 = models.OneToOneField(A, on_delete=xxx)
对于一对一的映射,两个模型类是对等状态,所以表示关系的属性可以放到两者任何一个模型中.
一旦在某个模型类中,增加了关联属性.把拥有关联属性的表称为从表,另一个称为主表.
外键类字段选项
特殊字段参数【必须项】:
其余常用的字段选项【非必须项】;如:
用法示例
创建作家和作家妻子类
# file : xxxxxxxx/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_delete=models.CASCADE) # 增加一对一属性
生成的oto_wife表关联字段名:author_id,并且有唯一约束.
创建一对一的数据记录
from .models import *
author1 = Author.objects.create(name='王老师')
wife1 = Wife.objects.create(name='王夫人', author=author1) # 关联王老师
author2 = Author.objects.create(name='小泽老师') # 一对一可以没有数据对应的数据
数据查询
正向查询
# 通过 wife 找 author
from .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, '还没有妻子')
作用: 垂直分表
主要是解决常用数据不常用数据的存储问题,把经常加载的一个数据放在主表中,不常用数据放在另一个副表中,这样在访问主表数据时不需要加载副表中的数据以提高访问速度提高效率和节省内存空间,如经常把书的内容和书名建成两张表,因为在网站上经常访问书名等信息,但不需要得到书的内容。
语法
class A(model.Model):
...
class B(model.Model):
属性 = models.ForeignKey("一"的模型类, on_delete=xx)
一对多,很明显不是对等关系,关联属性放到’多’模型类中.例如:班级对学员就是一对多关系,关联属性放到学员模型类中.
用法示例
清华大学出版社
有书
北京大学出版社
有书
创建模型类
# file: otm/models.py
from django.db import models
class Publisher(models.Model):
'''出版社【一】'''
name = models.CharField('名称', max_length=50, unique=True)
class Book(models.Model):
'''书【多】'''
title = models.CharField('书名', max_length=50)
publisher = ForeignKey(Publisher, on_delete=models.CASCADE)
一般模型类需要放到Django的后台管理中,最好重写模型类中的__str___方法
每添加新的应用和模型时,操作Django shell 需要退出shell重新进入
创建数据
#先创建 '一' ,再创建 '多'
from .models import *
pub1 = Publisher.objects.create(name='清华大学出版社')
Book.objects.create(title='C++', publisher=pub1)
Book.objects.create(title='Java', publisher_id=1)
#高级创建 - 利用 反向属性 [隐藏属性] book_set.
pub2 = Publisher.objects.create(name='北京大学出版社')
pub2.book_set.create(title='西游记')
数据查询
通过 Book 查询 Publisher【正向】
通过 publisher 属性查询即可
book.publisher
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)
语法
属性 = models.ManyToManyField(MyModel)
用法示例
class Author(models.Model):
...
class Book(models.Model):
...
authors = models.ManyToManyField(Author)
创建模型类
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
创建数据
方案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')
#郭小闹和吕老师都参与了 python1 的 创作
author3 = book.authors.create(name='guoxiaonao')
book.authors.add(author1)
数据查询
book.authors.all() -> 获取 book 对应的所有的author的信息
book.authors.filter(age__gt=80) -> 获取book对应的作者中年龄大于80岁的作者的信息
author.book_set.all()
author.book_set.filter()
具有关联关系的模型类也可以注册到后台数据库管理中,所以我们无需考虑底层sql中的表链接查询.即使以后开发
前台程序,前端和后端的交互通过json格式去封装的.
Cookies和Session就是为了保持会话状态而诞生的两个存储技术
cookies是保存在客户端浏览器上的存储空间
Chrome 浏览器 可能通过开发者工具的 Application
>> Storage
>> Cookies
查看和操作浏览器端所有的 Cookies 值
火狐浏览器 可能通过开发者工具的 存储 -> Cookie
在向服务器发送请求时,客户端浏览器会自动提交。
在Django 设置浏览器的COOKIE 必须通过 HttpResponse 对象来完成
添加、修改COOKIE
删除COOKIE
获取cookie
通过 request.COOKIES 绑定的字典(dict) 获取客户端的 COOKIES数据
value = request.COOKIES.get('cookies名', '默认值')
print("cookies名 = ", value)
示例
# 为浏览器添加键为 my_var1,值为123,过期时间为1个小时的cookie
responds = HttpResponse("已添加 my_var1,值为123")
responds.set_cookie('my_var1', 123, 3600)
return responds
# 为浏览器添加键为 my_var1,修改值为456,过期时间为2个小时的cookie
responds = HttpResponse("已修改 my_var1,值为456")
responds.set_cookie('my_var1', 456, 3600*2)
return responds
# 删除浏览器键为 my_var1的cookie
responds = HttpResponse("已删除 my_var1")
responds.delete_cookie('my_var1')
return responds
# 获取浏览器中 my_var变量对应的值
value = request.COOKIES.get('my_var1', '没有值!')
print("cookie my_var1 = ", value)
return HttpResponse("my_var1:" + value)
在服务器响应客户端时,可以设置cookies,也可以删除cookies,当客户再次请求服务器时,可以获取cookies。
session又名会话控制,是在服务器上开辟一段空间用于保留浏览器和服务器交互时的重要数据
实现方式
Django中配置Session
INSTALLED_APPS = [
# 启用 sessions 应用
'django.contrib.sessions',
]
MIDDLEWARE = [
# 启用 Session 中间件
'django.contrib.sessions.middleware.SessionMiddleware',
]
session的基本操作:
保存 session 的值到服务器
request.session['KEY'] = VALUE
例如:request.session[‘uname’] = 'tedu’这条语句的调用,首先在django_session表中,储存了key-value。并且
将sessionid(对应django_session表中的session_key)使用cookies存储到客户端。
获取session的值
VALUE = request.session['KEY']
VALUE = request.session.get('KEY', 缺省值)
下次请求服务器,浏览器会带着sessionid,就可以根据sessionid去查询数据库,得到session中保存过的数据。
删除session的值
在 settings.py 中有关 session 的设置
SESSION_COOKIE_AGE = 60 * 60 * 24 * 7 * 2
注: 当使用session时需要迁移数据库,否则会出现错误
python3 manage.py migrate
django 原生session 问题:
1,django_session表是 单表设计; 且该表数据量持续增持【浏览器故意删掉sessionid&过期数据未删除】
2,可以每晚执行 python3 manage.py clearsessions 【该命令可删除已过期的session数据】
存储位置:
C- 浏览器中 s- 服务器中【mysql】
安全性:
C - 不安全 s- 相对安全一些
不管C还是S , 不要存储敏感数据 【密码】
因篇幅问题不能全部显示,请点此查看更多更全内容