1.商业模式介绍
2项目知识点
B2B平台是电子商务的一种模式,是英文Business-to-Business的缩写,即商业对商业,或者说是企业间的电子商务,即企业与企业之间通过互联网进行产品、服务及信息的交换。它将企业内部网,通过B2B网站与客户紧密结合起来,通过网络的快速反应,为客户提供更好的服务,从而促进企业的业务发展
案例 阿里巴巴,
通过电子商务网站为买卖用户双方提供一个在线交易平台,使卖方可以在上面发布待出售的物品的信息,而买方可以从中选择进行购买,同时,为便于买卖双方交易,提供交易所需的一系列配套服务。如:协调市场信息汇集、建立信用评价制度、多种付款方式
案例 淘宝,闲鱼,瓜子二手车
B2C是Business to Customer的缩写,而其中文简称为“商对客”。“商对客”是电子商务的一种模式,也就是通常说的直接面向消费者销售产品和服务商业零售模式·这种形式的电子商务一般以网络零售业为主,主要借助于互联网开展在线销售活动·B2C即企业通过互联网为消费者提供一个新型的购物环境
—-网上商店,消费者通过网络在网上购物、网上支付等消费行为。
案例 唯品会,
·C2B(Consumer to Business,即消费者到企业),是互联网经济时代新的商业模式。这一模式改变了原有生产者(企业和机构)和消费者的关系,是一种消费者贡献价值(Create Value),企业和机构消费价值(Consume Value)。C2B模式和我们熟知的供需模式(DSM,Demand Supply Model)恰恰相反,真正的C2B应该先有消费者需求产生而后有企业生产,即先有消费者提出需求,后有生产企业按需求组织生产。通常情况为消费者根据自身需求定制产品和价格,或主动参与产品设计、生产和定价,产品、价格等彰显消费者的个性化需求,生产企业进行定制化生产。
案例 海尔商场,商品宅派
Live Server:一个具有实时加载功能的小型服务器,可以使用它来破解html/css/javascript,但是不能用于部署最终站点。也就是说我们可以在项目中实时用live-server作为一个实时服务器实时查看开发的网页或项目效果。
安装
npm install -g live-server
在所在项目目录下,打开命令行工具,输入 live-server,回车就可以了(注意这里默认打开的是index.html)。
默认端口 8080 可以指定端口 9000
live-server --port 9000
设置 wired
ipv4
手动设置
A类 10.0.0.0--10.255.255.255
B类 172.16.0.0--172.31.255.255
C类 192.168.0.0--192.168.255.255
Address 默认为ubuntu 的ip 用ifconfig 查看
Netmask c类 子网掩码 255.255.255.0
gateway 网关 192.168.17.2
dns 114.114.114.114,119.29.29.29
详情请到这里面
注意
_open
方法,_save
方法url
方法 用来访问文件exists
方法用来判断文件名是否重复,"""
继承Storage必须实现_open()和_save()方法
"""
class FastDFSStorage(Storage):
def __init__(self, client_path=None, base_url=None):
# fastDFS的客户端配置文件路径
self.client_path = client_path or settings.FDFS_CLIENT_CONF
# storage服务器ip:端口
self.base_url = base_url or settings.FDFS_BASE_URL
def _open(self, name, mode='rb'):
"""
用来打开文件的,但是我们自定义文件存储系统的目的是为了实现存储到远程的FastDFS服务器,不需要打开文件,所以此方重写后什么也不做pass
:param name: 要打开的文件名
:param mode: 打开文件的模式 read bytes
:return: None
"""
pass
def _save(self, name, content):
"""
文件存储时什么调用此方法,但是此方法默认是向本地存储,在此方法做实现文件存储到远程的FastDFS服务器
:param name: 要上传的文件名
:param content: 以rb模式打开的文件对象 将来通过content.read() 就可以读取到文件的二进制数据
:return: file_id
"""
# 1.创建FastDFS 客户端
# client = Fdfs_client('meiduo_mall/utils/fastdfs/client.conf')
# client = Fdfs_client(settings.FDFS_CLIENT_CONF)
client = Fdfs_client(self.client_path)
# 2.通过客户端调用上传文件的方法上传文件到fastDFS服务器
# client.upload_by_filename('要写上传文件的绝对路径') 只能通过文件绝对路径进行上传 此方式上传的文件会有后缀
# upload_by_buffer 可以通过文件二进制数据进行上传 上传后的文件没有后缀
ret = client.upload_by_buffer(content.read())
# 3.判断文件是否上传成功
if ret.get('Status') != 'Upload successed.':
raise Exception('Upload file failed')
# 3.1 获取file_id
file_id = ret.get('Remote file_id')
# 4.返回file_id
return file_id
def exists(self, name):
"""
当要进行上传时都调用此方法判断文件是否已上传,如果没有上传才会调用save方法进行上传
:param name: 要上传的文件名
:return: True(表示文件已存在,不需要上传) False(文件不存在,需要上传)
"""
return False
def url(self, name):
"""
当要访问图片时,就会调用此方法获取图片文件的绝对路径
:param name: 要访问图片的file_id
:return: 完整的图片访问路径: storage_server IP:8888 + file_id
"""
# return 'http://xxx.xxx.xxx.xx:8888/' + name
# return settings.FDFS_BASE_URL + name
return self.base_url + name
在Django中setting文件设置三个变量
# 指定Django使用的文件存储类 ,上面编写的py文件的路径
DEFAULT_FILE_STORAGE = 'utils.fdfs.storage.FastDFSStorage'
# 设置fdfs使用的client.conf文件路径 ,变量名自己取,与上面的py文件一致
FDFS_CLIENT_CONF = './utils/fdfs/client.conf'
# 设置fdfs存储服务器ngibx的ip和端口号,变量名自己取,与上面的py文件一致
FDFS_URL = 'http://xxx.xxx.xxx.xx:8888/'
具体见官方文档 https://docs.djangoproject.com/zh-hans/2.2/howto/custom-file-storage/
安装pip install django-ckeditor
注册应用
INSTALLED_APPS = [
......
'ckeditor', # 富⽂文本编辑器器
'ckeditor_uploader', # 富⽂文本编辑器器上传图⽚片模块
......
]
加载配置
# 富⽂文本编辑器器ckeditor配置
CKEDITOR_CONFIGS = {
'default': {
'toolbar': 'full', # ⼯工具条功能
'height': 300, # 编辑器器⾼高度
'width': 300, # 编辑器器宽
},
}
CKEDITOR_UPLOAD_PATH = '' # 上传图⽚片保存路路径,使⽤用了了FastDFS,所以此处设为''
注册总路由
re_path(r'^ckeditor/', include('ckeditor_uploader.urls')),
模型类补充富⽂文本字段
desc_detail = RichTextUploadingField(default='', verbose_name='详细介绍')
desc_pack = RichTextField(default='', verbose_name='包装信息')
desc_service = RichTextUploadingField(default='', verbose_name='售后服务')
修复bug适配FastDFS
if len(str(saved_path).split('.')) > 1:
if(str(saved_path).split('.')[1].lower() != 'gif'): self._create_thumbnail_if_needed(backend, saved_path)
实现全文检索的搜索引擎,首选的是
Elasticsearch
。
分词说明
搜索引擎在对数据构建索引时,需要进行分词处理。
分词是指将一句话拆解成多个单字或词,这些字或词便是这句话的关键词。
比如:
我是中国人
我
、是
、中
、国
、人
、中国
等等都可以是这句话的关键字。Elasticsearch 不支持对中文进行分词建立索引,需要配合扩展elasticsearch-analysis-ik
来实现中文分词处理。
1.获取Elasticsearch-ik镜像
# 从仓库拉取镜像
$ sudo docker image pull delron/elasticsearch-ik:2.4.6-1.0
# 本地镜像
$ sudo docker load -i elasticsearch-ik-2.4.6_docker.tar
2.配置Elasticsearch-ik
elasticsearc-2.4.6
目录拷贝到home
目录下
修改/home/ubuntu/Desktop/elasticsearc-2.4.6/config/elasticsearch.yml
第54行。
更改ip地址为本机真实ip地址。
3.使用Docker运行Elasticsearch-ik
sudo docker run -dti --name=elasticsearch --network=host -v /home/ubuntu/Desktop/elasticsearch-2.4.6/config:/us
1.Haystack介绍
Haystack
是在Django中对接搜索引擎的框架,搭建了用户和搜索引擎之间的沟通桥梁。
Haystack 可以在不修改代码的情况下使用不同的搜索后端(比如Elasticsearch
、Whoosh
、Solr
等等)。
2.Haystack安装
$ pip install django-haystack
$ pip install elasticsearch==2.4.1
3.Haystack注册应用和路由
INSTALLED_APPS = [
'haystack', # 全文检索
]
4.在setting中配置Haystack
# Haystack
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
'URL': 'http://192.168.17.132:9200/', # Elasticsearch服务器ip地址,端口号固定为9200
'INDEX_NAME': 'meiduo_mall', # Elasticsearch建立的索引库的名称
},
}
# 当添加、修改、删除数据时,自动生成索引
# HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
huaweip40
添加到购物车中,状态为勾选用户
,商品
,数量
,勾选状态
user_id
,sku_id
,count
,selected
存储 说明
这里,允许用户不登录,也能添加到购物车,利用浏览器的cookie 存储
密文存储
pickle模块
和base64模块
pickle模块使用:
pickle.dumps()
将Python数据序列化为bytes类型数据。pickle.loads()
将bytes类型数据反序列化为python数据。>>> import pickle
>>> dict = {'1': {'count': 10, 'selected': True}, '2': {'count': 20, 'selected': False}}
>>> ret = pickle.dumps(dict)
>>> ret
b'\x80\x03}q\x00(X\x01\x00\x00\x001q\x01}q\x02(X\x05\x00\x00\x00countq\x03K\nX\x08\x00\x00\x00selectedq\x04\x88uX\x01\x00\x00\x002q\x05}q\x06(h\x03K\x14h\x04\x89uu.'
>>> pickle.loads(ret)
{'1': {'count': 10, 'selected': True}, '2': {'count': 20, 'selected': False}}
base64.b64encode()
将bytes类型数据进行base64编码,返回编码后的bytes类型数据。base64.b64deocde()
将base64编码后的bytes类型数据进行解码,返回解码后的bytes类型数据。>>> import base64
>>> ret
b'\x80\x03}q\x00(X\x01\x00\x00\x001q\x01}q\x02(X\x05\x00\x00\x00countq\x03K\nX\x08\x00\x00\x00selectedq\x04\x88uX\x01\x00\x00\x002q\x05}q\x06(h\x03K\x14h\x04\x89uu.'
>>> b = base64.b64encode(ret)
>>> b
b'gAN9cQAoWAEAAAAxcQF9cQIoWAUAAABjb3VudHEDSwpYCAAAAHNlbGVjdGVkcQSIdVgBAAAAMnEFfXEGKGgDSxRoBIl1dS4='
>>> base64.b64decode(b)
b'\x80\x03}q\x00(X\x01\x00\x00\x001q\x01}q\x02(X\x05\x00\x00\x00countq\x03K\nX\x08\x00\x00\x00selectedq\x04\x88uX\x01\x00\x00\x002q\x05}q\x06(h\x03K\x14h\x04\x89uu.'
解决方法
让他自动寻址,分别输入,就可以ping通了:
xx@ubuntu:~/Desktop$ sudo ifconfig ens33 up
xx@ubuntu:~/Desktop$ sudo dhclient ens33
xx@ubuntu:~/Desktop$ sudo ifconfig ens33
参考 Ubuntu18.04解决网卡失效的问题
Ctrl+C,Ctrl+Shift+V
sudo apt install open-vm-tools
sudo apt install open-vm-tools-desktop
# 重启
reboot
apt install netscript
概念
请求次数相关
,则称接⼝口⾮非幂等场景
PUT/cart/
count 商品数量 原始值 10
方式1 count 表示 商品数量 +1 -->后端执行加1操作,===>非幂等
PUT /cart/ count=1 --> 11
PUT /cart/ count=1 --> 12
PUT /cart/ count=1 --> 13
方式1 count 表示 修改之后的结果 -->后端执行覆盖原有值,===>幂等
PUT /cart/ count=1 --> 1
PUT /cart/ count=1 --> 1
PUT /cart/ count=13 --> 13
1.Django中事务的使用方案
django.db.transaction模块
提供的atomic
来定义一个事务。atomic
提供两种方案实现事务:
装饰器用法:
from django.db import transaction
@transaction.atomic
def viewfunc(request):
# 这些代码会在一个事务中执行
......
with语句用法:
from django.db import transaction
def viewfunc(request):
# 这部分代码不在事务中,会被Django自动提交
......
with transaction.atomic():
# 这部分代码会在事务中执行
......
2.事务方案的选择:
3.事务中的保存点:
from django.db import transaction
# 创建保存点
save_id = transaction.savepoint()
# 回滚到保存点
transaction.savepoint_rollback(save_id)
# 提交从保存点到当前状态的所有数据库事务操作
transaction.savepoint_commit(save_id)
原因
注意 使用乐观锁的时候,如果一个事务修改了库存并提交了事务,那其他的事务应该可以读取到修改后的数据值,所以不能使用可重复读的隔离级别,应该修改为读取已提交(Read committed)
Serializable
:串行化,一个事务一个事务的执行。Repeatable read
:可重复读,无论其他事务是否修改并提交了数据,在这个事务中看到的数据值始终不受其他事务影响。Read committed
:读取已提交,其他事务提交了对数据的修改后,本事务就能读取到修改后的数据值。Read uncommitted
:读取未提交,其他事务只要修改了数据,即使未提交,本事务也能看到修改后的数据值。sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf
修改完成之后重启
sudo service mysql restart
transaction-isolation=READ-COMMITTED
支付宝开放平台入口
登录 账号
控制台
创建应用
沙箱环境
沙箱环境
支付宝提供给开发者的模拟支付的环境。跟真实环境是分开的。
文档主页: https://openhome.alipay.com/developmentDocument.htm
电脑网站支付产品介绍: https://docs.open.alipay.com/270
电脑网站支付快速接入: https://docs.open.alipay.com/270/105899/
API列表: https://docs.open.alipay.com/270/105900/
SDK文档: https://docs.open.alipay.com/270/106291/
Python支付宝SDK: 这里使用第三方编写,调用简洁
https://github.com/fzlee/alipay/blob/master/README.zh-hans.md
pip install python-alipay-sdk --upgrade
生成项目公钥
$ openssl
$ OpenSSL> genrsa -out app_private_key.pem 2048 # 制作私钥RSA2
$ OpenSSL> rsa -in app_private_key.pem -pubout -out app_public_key.pem # 导出公钥
$ OpenSSL> exit
notify_url=" ",
此参数一定要写,Str类型
# 生成登录支付宝连接
order_string = alipay.api_alipay_trade_page_pay(
out_trade_no=order_id,
total_amount=str(order.total_amount),
subject="美多商城%s" % order_id,
return_url=settings.ALIPAY_RETURN_URL,
notify_url=" ",
app_private_key_string = open(settings.APP_PRIVATE_KEY_PATH).read()
alipay_public_key_string = open(settings.ALIPAY_PUBLIC_KEY_PATH).read()
# 创建支付宝对象
alipay = AliPay(
appid=settings.ALIPAY_APPID,
app_notify_url=None, # 默认回调url
app_private_key_string=app_private_key_string,
# 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥,
alipay_public_key_string=alipay_public_key_string,
sign_type='RSA2',
debug=True
)
print("打印参数》》》》》")
print(type(settings.ALIPAY_RETURN_URL))
print("执行》》》》》》》")
# 生成登录支付宝连接
order_string = alipay.api_alipay_trade_page_pay(
out_trade_no=order_id,
total_amount=str(order.total_amount),
subject="美多商城%s" % order_id,
return_url=settings.ALIPAY_RETURN_URL,
notify_url=" ",
)
# 生成登录支付宝连接
# 3.0 接口方法
order_string = alipay.client_api(
"alipay.trade.page.pay",
biz_content={
"subject": "美多商城%s" % order_id,
"out_trade_no": order_id,
"total_amount": str(order.total_amount),
"product_code": "FAST_INSTANT_TRADE_PAY",
},
return_url=settings.ALIPAY_RETURN_URL,
)
# 响应登录支付宝连接
# 真实环境电脑网站支付网关:https://openapi.alipay.com/gateway.do? + order_string
# 沙箱环境电脑网站支付网关:https://openapi.alipaydev.com/gateway.do? + order_string
alipay_url = settings.ALIPAY_URL + "?" + order_string
# print("alipay_url")
# print(alipay_url)
return JsonResponse({'code': 0, 'errmsg': 'OK', 'alipay_url': alipay_url})
pip install https://github.com/sshwsfc/xadmin/tarball/
win10 解决 https://blog.csdn.net/teavamc/article/details/75400755
# xadmin 配置
'xadmin',
'crispy_forms',
'reversion',
python manage.py makemigrations
作用
通过增加从服务器来提⾼数据库的性能,在主服务器上执⾏写⼊和更新,在从服务器器上向外提供读功能,可以动态地调整从服务器器的数量,从⽽调整整个数据库的性能。
提⾼数据安全,因为数据已复制到从服务器,从服务器可以终止复制进程,所以,可以在从服务器上备份⽽不破坏主服务器相应数据
在主服务器上生成实时数据,而在从服务器器上分析这些数据,从而提高主服务器的性能
同步机制
1.先执行冷备份
2.再执行热备份
注意: mysql 主从机的版本,不要相差太大
修改从机配置文件
# 修改端口
port = 8306
# 是否生成日志文件 0 不生成 1生成
general_log_file = /var/log/mysql/mysql.log
general_log = 0
# 主机 为1
# 修改从机
server-id = 2
主机配置
server-id = 1
# log日志文件
log_bin = /var/log/mysql/mysql-bin.log
重启主机的mysql
创建从机账号
mysql –uroot –pmysql
GRANT REPLICATION SLAVE ON *.* TO 'slave'@'%' identified by 'slave';
FLUSH PRIVILEGES;
获取mysql主机的二进制日志信息
在主机上 SHOW MASTER STATUS;
说明
file >> 从机热备份时读取数据的文件
Position >> 从机热备份时读取数据的位置,节点
在从机上 SHOW MASTER STATUS;
pip install djangorestframework
INSTALLED_APPS = [
...
'rest_framework',
]
模型类
from django.db import models
# Create your models here.
# 准备书籍列表信息的模型类
class BookInfo(models.Model):
# 创建字段,字段类型...
name = models.CharField(max_length=20, verbose_name='名称')
pub_date = models.DateField(verbose_name='发布日期',null=True)
breadcount = models.IntegerField(default=0, verbose_name='阅读量')
bcommentcount = models.IntegerField(default=0, verbose_name='评论量')
is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')
image = models.ImageField(upload_to='book', null=True, verbose_name='图片')
class Meta:
db_table = 'bookinfo' # 指明数据库表名
verbose_name = '图书' # 在admin站点中显示的名称
def __str__(self):
"""定义每个数据对象的显示信息"""
return self.name
# 准备人物列表信息的模型类
class HeroInfo(models.Model):
hname = models.CharField(max_length=20, verbose_name='名称')
hgender = models.IntegerField(max_length=20,verbose_name='密码')
hdesc = models.CharField(max_length=200, null=True, verbose_name='描述信息')
hbook = models.ForeignKey(BookInfo,related_name='people', on_delete=models.CASCADE, verbose_name='图书') # 外键
is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')
class Meta:
db_table = 'heroinfo'
verbose_name = '人物信息'
def __str__(self):
return self.hname
创建serializers.py
文件
from rest_framework import serializers
from book.models import BookInfo
class PeopleInfoSerializer(serializers.Serializer):
"""英雄数据序列化器"""
id = serializers.IntegerField(label='ID')
hname = serializers.CharField(label='名字')
hgender = serializers.IntegerField(label="性别")
hdesc = serializers.CharField(label="描述信息")
"""定义序列化器"""
class BookInfoSerializer(serializers.Serializer):
"""图书数据序列化器"""
id = serializers.IntegerField(label='ID')
name = serializers.CharField(label='名称')
pub_date = serializers.DateField(label='发布日期')
breadcount = serializers.IntegerField(label='阅读量')
bcommentcount = serializers.IntegerField(label='评论量')
# 一对多的序列化器
people = PeopleInfoSerializer(many=True)
class PeopleSerializer(serializers.Serializer):
"""英雄数据序列化器"""
id = serializers.IntegerField(label='ID')
hname = serializers.CharField(label='名字')
hgender = serializers.IntegerField(label="性别")
hdesc = serializers.CharField(label="描述信息")
# hbook_id = serializers.IntegerField(label="图书id")
# hbook = serializers.PrimaryKeyRelatedField(label='图书',read_only=True) # 不能被反序列化
# hbook = serializers.PrimaryKeyRelatedField(label='图书',queryset=BookInfo.objects.all())
# # 此字段将被序列化为关联对象的字符串表示方式(即__str__方法的返回值)
# hbook = serializers.StringRelatedField(label="图书")
# # 图书的序列化信息
hbook = BookInfoSerializer()
序列化输出
from book.models import BookInfo,HeroInfo
hero = HeroInfo.objects.get(id=3)
from book.serializers import PeopleSerializer
hero_ser = PeopleSerializer(hero)
hero_ser.data
反序列化器
写一个 字典
创建 序列化器对象 serializer
验证
保存
代码
from book.models import BookInfo,HeroInfo
from book.serializers import PeopleSerializer, BookInfoSerializer
data = {
'name':'Python高级',
'pub_date':'2020-1-1',
'breadcount':100,
'bcommentcount':200,
}
# 创建序列化对象
book = BookInfoSerializer(data=data)
# 验证 返回 True False
book.is_valid()
# 查看报错信息
book.errors
# 返回 {}
is_valid()
方法还可以在验证失败时抛出异常serializers.ValidationError,可以通过传递raise_exception=True参数开启,REST framework接收到此异常,会向前端返回HTTP 400 Bad Request响应。
read__only和write__only 不能同时出现
**验证字段方法validate_filedname **
可以 进行正则判断,
validate
在序列化器中需要同时对多个字段进行比较验证时,可以定义validate方法来验证,如
def validate(self, attrs):
readcount = attrs['readcount']
commentcount = attrs['commentcount']
if commentcount > readcount:
raise serializers.ValidationError('评论量不能大于阅读量')
return attrs
保存
保存到数据库,
# 序列化器类,定义create 方法
def create(self, validated_data):
"""新建"""
return BookInfo.objects.create(**validated_data)
代码
**注意: 如果创建序列化器对象的时候,没有传递instance实例,则调用save()方法的时候,create()被调用。 **
>>> from book.serializers import BookInfoSerializer
>>>
>>> data = {
... 'name':'Python高级',
... 'pub_date':'2020-01-01',
... 'readcount':100,
... 'commentcount':20
... }
>>>
>>> serializer = BookInfoSerializer(data=data)
>>>
>>> serializer.is_valid(raise_exception=True)
True
>>>
>>> serializer.save()
更新
def update(self, instance, validated_data):
"""更新,instance为要更新的对象实例"""
instance.name = validated_data.get('name', instance.name)
instance.pub_date = validated_data.get('pub_date', instance.pub_date)
instance.readcount = validated_data.get('readcount', instance.readcount)
instance.commentcount = validated_data.get('commentcount', instance.commentcount)
instance.save()
return instance
**注意: 如果创建序列化器对象的时候,如果传递了instance实例,则调用save()方法的时候,update()被调用。**
测试
>>> from book.serializers import BookInfoSerializer
>>> from book.models import BookInfo
>>>
>>> book = BookInfo.objects.get(id=5)
>>>
>>> data = {
... 'name':'Django高级',
... 'pub_date':'2020-01-01',
... 'readcount':100,
... 'commentcount':20
... }
>>>
>>> serializer = BookInfoSerializer(instance=book,data=data)
>>>
>>> serializer.is_valid(raise_exception=True)
True
>>>
>>> serializer.save()
>>>
小结
instance
则 是保存 到数据库,自动调用 create方法
instance
则 是更新 到数据库,自动调用 update方法
1) 在对序列化器进行save()保存时,可以额外传递数据,这些数据可以在create()和update()中的validated_data参数获取到
serializer.save(user=request.user)
2)默认序列化器必须传递所有required的字段,否则会抛出验证异常。但是我们可以使用partial参数来允许部分字段更新
serializer = BookInfoSerializer(instance=book, data={'pub_date': '2999-1-1'}, partial=True)
from rest_framework import serializers
from book.models import BookInfo
class BookInfoModelSerializer(serializers.ModelSerializer):
class Meta:
model = BookInfo # 必须指定模型类
fields = '__all__' # 默认生成字段
# 可以自己指定字段
# fields = ["id", "name"]
# 除去列表中的字段
# exclude = ["is_delete"]
subs = AreaSerializer(many=True) # subs 是省下面的所有的市区县
# subs = serializers.PrimaryKeyRelatedField() # 只会序列化出 id
# subs = serializers.StringRelatedField() # 序列化的时模型中str方法返回值
扩展 Request
# Django自带的 request.GET
# 扩展 request.query_params
======================
# Django自带的 request.POST
# 扩展 request.data
扩展 Response
REST framework提供了Renderer
渲染器,用来根据请求头中的Accept
(接收数据类型声明)来自动转换响应数据到对应格式。如果前端请求中未进行Accept声明,则会采用默认方式处理响应数据,我们可以通过配置来修改默认响应格式。
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': ( # 默认响应渲染类
'rest_framework.renderers.JSONRenderer', # json渲染器
'rest_framework.renderers.BrowsableAPIRenderer', # 浏览API渲染器
)
}
构造方式
Response(data, status=None, template_name=None, headers=None, content_type=None)
参数说明:
data
: 为响应准备的序列化处理后的数据;status
: 状态码,默认200;template_name
: 模板名称,如果使用HTMLRenderer
时需指明;headers
: 用于存放响应头信息的字典;content_type
: 响应数据的Content-Type,通常此参数无需传递,REST framework会根据前端所需类型数据来设置该参数。APIView
与View
的不同之处在于:
Request
对象,而不是Django的HttpRequeset
对象;Response
对象,视图会为响应数据设置(render)符合前端要求的格式;APIException
异常都会被捕获到,并且处理成合适的响应信息;pk
’注意Mixin 配合GenericAPIView
1)ListModelMixin
列表视图扩展类,提供list(request, *args, **kwargs)
方法快速实现列表视图,返回200状态码。
该Mixin的list方法会对数据进行过滤和分页。
2)CreateModelMixin
创建视图扩展类,提供create(request, *args, **kwargs)
方法快速实现创建资源的视图,成功返回201状态码。
如果序列化器对前端发送的数据验证失败,返回400错误
详情文档
安装
pip3 install drf-extensions
1.装饰器的方式
**继承视图 CacheResponseMixin **
setting 设置缓存时间
# drf缓存时间
REST_FRAMEWORK_EXTENSIONS = {
# 设置为5秒
'DEFAULT_CACHE_RESPONSE_TIMEOUT': 5
}
官网文档:http://chibisov.github.io/drf-extensions/docs