搭建前奏
打开pycharm,建立day71的程序,如图
项目建好以后在settings里面进行简单配置,如图所示
然后简单地进行数据库的配置:
接下来再在settings里面注册,如图:
配置文件完成后再做一个路由分发,如图:
接下来在总路由中进行路由分发与查找照片的相应配置,如图:
再下来就是在__init__中进行连接数据库的相应配置,如图
接着在settings进行全局配置,看图
基础的结构配置已完成,接下来在models里面进行表的创建,如图:创建表所需的字段
先创建一个基表,基表 : 基表的class Mate一定要加上abstract = True,因为该表是提供共有字段的,不是用来创表的如果创建表就要继承我,如果不想增加新的字段就继承我就行,若果想加新的字段,就在我的基础上增加新的字段。
还有提一个就是模型类的封装就是共有类的封装,依据是abstract的Meta里面规定的
# 作为基表的Model不能在数据库中形成对应的表
class Meta:
abstract = True
class Book(BaseModel):
name = models.CharField(max_length=64)
price = models.DecimalField(max_digits=5, decimal_places=2)
image = models.ImageField(upload_to='img', default='image/default.jpg')
publish = models.ForeignKey(to='Publish')
authors = models.ManyToManyField(to='Author')
class Meta:
db_table = 'book'
verbose_name = '书籍'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
# 序列化插拔式属性===》完成自定义字段名完成连表查询
@propery
def publish_name(self)
return self.publish.name
class Publish(BaseModel):
name = models.CharField(max_length=64)
address = models.CharField(max_length=64)
class Meta:
db_table = 'publish'
verbose_name = '出版社'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
class Author(BaseModel):
name = models.CharField(max_length=64)
age = models.IntegerField()
class Meta:
db_table = 'author'
verbose_name = '作者'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
def get_sex(self, obj):
# choice类型的解释性值, get_字段_display() 来访问
return obj.get_sex_display
class AuthorDetail(BaseModel):
mobile = models.CharField(max_length=11)
author = models.OneToOneField(to='Author')
class Meta:
db_table = 'author_detail'
verbose_name = '作者详情'
verbose_name_plural = verbose_name
def __str__(self):
return '%s的详情' % self.author.name
知识兔表建好以后进行数据库的创建,然后连接数据库,将数据迁移在数据库里面,如图
表成功迁移至是数据库
2. 多表断关联
1,创建超级用户,在app01下的admin进行注册,如图
现在就开始断关系,来到models模块里面,作者被删,那么作者详情也就会被删,如图,related_name = detail叫做反向查询 , db_constraint=False 断关联
在根目录下建立script/model.py的测试脚本,如图
django脚本化启动
运行django脚本化并不是运行manage.py,运行结果:
在这边拓展下级联关系,比如,书籍是作者写的,写这本书的人西去了,那么这本书的作者还是有的,并且还是他,最鲜明的例子就是《西游记》,这就叫do_nothing,还有一个叫set_default,另外一个叫做SET_NULL,
当unll=true, on_delete = models.SET_NULL时,会出现作者被删除,外键被删除,
作者被删除
外键被置空
当设置为on_delete = models.SET_DEFAULT, default = true时,如图, 详情重置
当设置为do_nothing时,如图:在现实生活中只是改了下字段,如图
作者会被删掉
外键什么的都没变
总体来说,四种关系是这样的
manytomany不能直接设置on_delete,要在第三张表中设置才可以
三 . 多表序列化组件
序列化层: app01/serializers.py
# 所有字段
fields = ‘__all__’
# 刨除。。不展示, 不能与fields同用
exclude = ('id', 'is_delete')
知识兔
视图层: app01/views.py
# 序列化对象
book_data = serializers.BookModelSerializer(book_obj).data
print(book_data)
except:
return Response({
'status': 1,
'msg': '书籍不存在'
})
else:
book_query = models.Book.objects.all()
book_data = serializers.BookModelSerializer(book_query,many=True).data #
return Response({
'status': 0,
'msg': 'ok',
'results': book_data
})
知识兔路由层: app01/urls.py
rlpatterns = [
url(r'^books/$', views.Book.as_view()),
url(r'^books/(?P<pk>.*)/$', views.Book.as_view()),
]
知识兔
四. 自定义子序列化深度连表查询
自定义深度查询
rom rest_framework.serializers import ModelSerializer
from . import models
class PublishModelSerializer(ModelSerializer):
class Meta:
model = models.Publish
fields = ('name', 'address')
class BookModelSerializer(ModelSerializer):
# 自定义连表深度 - 子序列化方法
publish = PublishModelSerializer() # 相当于调用了class PublishModelSerializer这个类,对其外键完成深度序列化
class Meta:
# 序列化类关联的model类
model = models.Book
# 参与序列化的字段
fields = ('name', 'price','publish') # 往前台返回的字段
# fields = '__all__'
知识兔效果如图:
五. 多表反序列化组件
序列化层: api/serializers.py
视图层: app01/views.py
效果如下:
局部钩子与全局钩子的校验
# 序列化类已经将外键转化为对象
name = attrs.get('name')
if models.Book.objects.filter(name=name, publish=publish):
raise ValidationError({'book': '改书已存在'})
return attrs
# ModelSerializer类已经帮我们实现了create与updata方法
知识兔视图层:
当校验失败,马上终止当前视图方法,抛异常返回给前台
book_ser.is_valid(raise_exception=True) #检验是否合格 raise_exception=True必填的
book_obj = book_ser.save() #保存
return Response({
'status':0,
'msg':'ok',
'results':serializers.BookModelSerializers(book_obj).data
})
知识兔
六 .序列化与反序列化的整合(************)
序列化层:
requirred是否是必须的
'min_length': 1,
'error_messages': {
'required': '必填项', # 将原来没有传照片的提示改变为‘必须填’
'min_length': '太短',
}
},
'publish': {
'write_only': True
},
'authors': {
'write_only': True
},
'img': {
'read_only': True,
},
'author_list': {
'read_only': True,
},
'publish_name': {
'read_only': True,
}
}
def validate_name(self, value):
# 书名不能包含 g 字符
if 'g' in value.lower():
raise ValidationError('该g书不能出版')
return value
def validate(self, attrs):
publish = attrs.get('publish')
name = attrs.get('name')
if models.Book.objects.filter(name=name, publish=publish):
raise ValidationError({'book': '该书已存在'})
return attrs
知识兔序列化注意点:
write_only:只反序列化
read_only:只序列化
自定义字段默认只序列化(read_only)
如果字段没设置write_only或者read_only,那么该字段可以序列化和反序列化
3) 设置反序列化所需的 系统、局部钩子、全局钩子 等校验规则
知识兔视图层. views.py
# many = true 多条数据
book_data = serializers.V2BookModelSerializer(book_query,many=True).data #序列化
return Response({
'status':0,
'msg':'ok',
'results':book_data
})
def post(self,request,*args,**kwargs):
#单增:传的数据是与model对应的一个字典
# 群增:设计传递的是多个model对应的字典列表
request_data = request.data
if isinstance(request_data,dict):
many = False
elif isinstance(request_data,list): #在postman中设计一个列表存入每条数据
many = True
else:
return Response({
'status':1,
'msg':'数据错误'
})
book_ser = serializers.V2BookModelSerializer(data=request_data,many=many) #反序列化
book_ser.is_valid(raise_exception=True)
book_result = book_ser.save() #book_result是对象<class 'app01.models.Book'>,如果增加多个就是列表套一个个对象
return Response({
'status':0,
'msg':'ok',
'results':serializers.V2BookModelSerializer(book_result,many=many).data
})
#单删: 有pk #在postman中通过路径传参
#群删:有pks {"pks": [1, 2, 3]} #通过json传参 两者都不需要序列化,只是将数据库中的0变为1
def delete(self,request,*args,**kwargs):
pk = kwargs.get('pk')
if pk: # 单删
pks = [pk]
else: # 群删
pks = request.data.get('pks')
if models.Book.objects.filter(pk__in=pks,is_delete=False).update(is_delete=True):
return Response({
'status':0,
'msg':'删除成功'
})
return Response({
'status':1,
'msg':'删除失败'
})
知识兔视图层注意点:(*****)
1.序列化数据最后必须要.data
2.反序列化通过data传参
3.反序列化与序列化都能使用many=True
知识兔路由层: urls.py
rlpatterns = [
url(r'^v2/books/$', views.V2Book.as_view()),
url(r'^v2/books/(?P<pk>.*)/$', views.V2Book.as_view()),
]
知识兔