2020年11月22日星期日

drf—— Book系列连表接口

注意:

# 注意:以后所有的数据删除,尽量用软删除,使用一个字段标志是否删除,而不是真正的从数据库中删除 -好处:1 这样删除数据不会影响索引,不会导致索引失效   2 之前存的用户数据还在,以备以后使用

models.py--->数据迁移

# 抽象出一个基表(不再数据库生成,abstract=True),只用来继承class BaseModel(models.Model): is_delete = models.BooleanField(default=False) create_time = models.DateTimeField(auto_now_add=True) class Meta:  # 基表必须设置abstract,基表就是给普通Model类继承使用的,设置了abstract就不会完成数据库迁移完成建表  abstract = Trueclass Book(BaseModel): name = models.CharField(max_length=16) price = models.DecimalField(max_digits=5, decimal_places=2) publish = models.ForeignKey(to='Publish', db_constraint=False, on_delete=models.DO_NOTHING) # 重点:多对多外键实际在关系表中,ORM默认关系表中两个外键都是级联 # ManyToManyField字段不提供设置on_delete,如果想设置关系表级联,只能手动定义关系表 authors = models.ManyToManyField(to='Author', related_name='books', db_constraint=False) @property def publish_name(self):  return self.publish.name @property def author_list(self):  # ll=[]  # for author in self.authors.all():  #  ll.append({'name':author.name,'sex':author.get_sex_display()})  return [{'name': author.name, 'sex': author.get_sex_display()} for author in self.authors.all()]class Publish(BaseModel): name = models.CharField(max_length=16) address = models.CharField(max_length=64)class Author(BaseModel): name = models.CharField(max_length=16) sex = models.IntegerField(choices=[(0, '男'), (1, '女')], default=0)class AuthorDetail(BaseModel): mobile = models.CharField(max_length=11) # 有作者可以没有详情,删除作者,详情一定会被级联删除 # 外键字段为正向查询字段,related_name是反向查询字段 author = models.OneToOneField(to='Author', related_name='detail', db_constraint=False, on_delete=models.CASCADE)

admin.py

from django.contrib import adminfrom app01 import modelsadmin.site.register(models.Book)admin.site.register(models.Publish)admin.site.register(models.Author)admin.site.register(models.AuthorDetail)

创建一个超级用户,登录admin后台管理,造出一些数据(books ,authors,publish)

serializer.py

# 图书表序列化类from app01 import modelsfrom rest_framework import serializersclass ListBookSerializer(serializers.ListSerializer): # def create(self, validated_data): #  print('=======',validated_data) #  return '1' def update(self, instance, validated_data):  print(instance) # book_list:是一堆图书对象  print(validated_data) # 列表套字典,是要修改的数据  return [self.child.update(book, validated_data[i]) for i, book in enumerate(instance)]class BookSerializer(serializers.ModelSerializer): class Meta:  model = models.Book  list_serializer_class=ListBookSerializer # 指定many=True的时候,生成的ListBookSerializer的对象了  fields = ['name', 'price', 'publish', 'authors', 'publish_name', 'author_list']  extra_kwargs = {   'publish': {'write_only': True},   'authors': {'write_only': True},   'publish_name': {'read_only': True},   'author_list': {'read_only': True},  } # def create(self, validated_data): #  print(validated_data)

utils.py

from rest_framework.response import Responseclass APIResponse(Response): def __init__(self, code=100, msg='成功', data=None, status=None,     headers=None, content_type=None, **kwargs):  dic = {'code': code, 'msg': msg}  if data:   dic['data'] = data  dic.update(kwargs)  super().__init__(data=dic, status=status, headers=headers, content_type=content_type)from rest_framework.views import exception_handlerdef common_exception(exc, context): # 先调用REST framework默认的异常处理方法获得标准错误响应对象 response = exception_handler(exc, context) # 在此处补充自定义的异常处理 if response is None:  response = Response(data={'code':999,'msg':str(exc)}) return response

settings.py

INSTALLED_APPS = [ ... 'rest_framework']REST_FRAMEWORK = { # 配置全局异常 'EXCEPTION_HANDLER': 'app01.utils.common_exception'}

 

views.py

# book表单增群增from app01 import serializerfrom app01 import modelsfrom rest_framework.views import APIViewfrom app01.utils import APIResponseclass BookView(APIView): def post(self, request, *args, **kwargs):  if isinstance(request.data, dict):   # 增一条   ser = serializer.BookSerializer(data=request.data)   ser.is_valid(raise_exception=True)   ser.save()   return APIResponse(data=ser.data)  elif isinstance(request.data, list):   # 增多条(让many=True就可以了)   ser = serializer.BookSerializer(data=request.data, many=True)   # 内部如何实现的?   # many=True,ser不是BookSerializer对象,而是ListSerializer对象,套了一个个的BookSerializer   print(type(ser))   ser.is_valid(raise_exception=True)   #   from rest_framework.serializers import ListSerializer   ser.save() # ListSerializer的save   return APIResponse(msg='增加%s条成功' % len(request.data)) def get(self, request, *args, **kwargs):  pk = kwargs.get('pk', None)  if pk:   # 单查   # 方式一   # book=models.Book.objects.filter(id=pk).filter(is_delete=False).first()   # if not book:   #  raise Exception('要查询的不存在')   # 方式二   book = models.Book.objects.get(id=pk, is_delete=False)   ser = serializer.BookSerializer(instance=book)  else:   # 查所有   book_list = models.Book.objects.all().filter(is_delete=False)   ser = serializer.BookSerializer(instance=book_list, many=True)  return APIResponse(data=ser.data) def delete(self, request, *args, **kwargs):  pk = kwargs.get('pk', None)  pks = []  if pk:   # 单条删除   # res=models.Book.objects.filter(id=pk).update(is_delete=True)   # print(res)   # return APIResponse(msg='删除成功')   pks.append(pk)  else:   pks = request.data  res = models.Book.objects.filter(id__in=pks).update(is_delete=True)  if res >= 1:   return APIResponse(msg='删除%s条成功' % res)  else:   # raise Exception('没有要删除的数据')   return APIResponse(code=999, msg='没有要删除的数据') def put(self, request, *args, **kwargs):  pk = kwargs.get('pk', None)  if pk:   # 单条修改   book = models.Book.objects.get(id=pk, is_delete=False)   ser = serializer.BookSerializer(instance=book, data=request.data)   ser.is_valid(raise_exception=True)   ser.save()   return APIResponse(msg='修改成功')  else:   # 分析:ListSerializer的update方法没有写,需要我们自己写   from rest_framework.serializers import ListSerializer   # pks=[item['id'] for item in request.data]   # 如果不重写ListSerializer的update方法,这是存不进去的   pks = []   for item in request.data:    pks.append(item['id'])    item.pop('id')   print(request.data)   book_list = models.Book.objects.filter(id__in=pks, is_delete=False)   ser = serializer.BookSerializer(instance=book_list, data=request.data, many=True)   print(type(ser))   ser.is_valid(raise_exception=True)   ser.save()   return APIResponse(msg='修改%s条成功')

urls.py

from django.contrib import adminfrom django.urls import pathfrom app01 import viewsurlpatterns = [ ### book表 path('books/', views.BookView.as_view()), re_path('books/(?P<pk>\d+)', views.BookView.as_view()),]

 









原文转载:http://www.shaoqun.com/a/492776.html

vat:https://www.ikjzd.com/w/109

败欧洲:https://www.ikjzd.com/w/1555

韩国naver:https://www.ikjzd.com/w/1727


注意:#注意:以后所有的数据删除,尽量用软删除,使用一个字段标志是否删除,而不是真正的从数据库中删除-好处:1这样删除数据不会影响索引,不会导致索引失效2之前存的用户数据还在,以备以后使用models.py--->数据迁移#抽象出一个基表(不再数据库生成,abstract=True),只用来继承classBaseModel(models.Model):is_delete=models.Boo
壹米滴答:壹米滴答
landing:landing
干货|如何更好撰写Search Terms内容提高搜索流量?:干货|如何更好撰写Search Terms内容提高搜索流量?
中山泉林山庄好玩吗?:中山泉林山庄好玩吗?
景德镇美食小吃 - :景德镇美食小吃 -

没有评论:

发表评论