十大接口

drf 十大接口

序列化外键字段的覆盖

在序列化类中自定字段,名字与model类中属性名一致,就称为覆盖操作(覆盖的是属性的所有规则:extra kwargs中指定的简易规则、model字段提供的默认规则、数据库唯一约束等那些规则)

外键覆盖字段用PriaryKeyRekatedField来实现,可以做到只读只写、可读可写三种形式

  • 只读:read_only=True
  • 只写:querset=关键表达 queryset,write_only=True
  • 可读可写:queryset=关联表的queryset
  • 当外界关联的数据是多个时,需标识many=True条件
class BookModelSerializer(serializers.ModelSerializer):
    # 如何覆盖外键字段
    # publish = serializers.PrimaryKeyRelatedField(read_only=True)  # 只读
    # publish = serializers.PrimaryKeyRelatedField(queryset=models.Publish.objects.all(), write_only=True)  # 只写
    # publish = serializers.PrimaryKeyRelatedField(queryset=models.Publish.objects.all())  # 可读可写

    publish = serializers.PrimaryKeyRelatedField(queryset=models.Publish.objects.all())
    authors = serializers.PrimaryKeyRelatedField(queryset=models.Author.objects.all(), many=True)

    class Meta:
        model = models.Book
        fields = ('name', 'price', 'image', 'publish', 'authors')

十大接口

# models.py
from django.db import models

# Create your models here.
# 基类:抽象概念,这个是不会完成数据迁移的,目的是提供共有的字段

class BaseModel(models.Model):
    is_delete = models.BooleanField(default=False)
    # auto_now_add 自动生成时间,不要手动加时间
    create_time = models.DateTimeField(auto_now_add=True, )
    last_update_time = models.DateTimeField(auto_now=True)
    # import  datetime
    # create_time = models.DateTimeField(default=datetime.datetime.now)
    class Meta:
        # 单个字段,有索引,联合唯一
        # 联合唯一,有联合索引,联合唯一
        abstract = True # 不在数据库中建表


class Book(BaseModel):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32,verbose_name='图书')
    price = models.DecimalField(max_digits=5, decimal_places=2,verbose_name='价格')
    # db_constraint=False,逻辑上的关联,增删改没问图
    publish = models.ForeignKey('Publish', on_delete=models.DO_NOTHING, db_constraint=False,verbose_name='关联出版社')
    authors = models.ManyToManyField('Authors', db_constraint=False,verbose_name='关联作者')

    class Meta:
        verbose_name_plural= '图书表'

    def __str__(self):
        return self.name

    @property
    def publish_name(self):
        return self.publish.name


    def author_list(self):
        return [{"name": author.name, "sex": author.get_sex_display()} for author in self.authors.all()]



class Publish(BaseModel):
    name = models.CharField(max_length=32,verbose_name='出版社')
    addr = models.CharField(max_length=32,verbose_name='地址')

    class Meta:
        verbose_name_plural='出版社'

    def __str__(self):
        return self.name
class Authors(BaseModel):
    name = models.CharField(max_length=32,verbose_name='姓名')
    sex = models.IntegerField(choices=((1, '男'), (2, '女')),verbose_name='性别')
    authordetail = models.OneToOneField('AuthorsDetail', db_constraint=False, on_delete=models.CASCADE,verbose_name='关联作者详情')

    class Meta:
        verbose_name_plural = '作者'

    def __str__(self):
        return self.name

class AuthorsDetail(BaseModel):
    mobile = models.CharField(verbose_name='手机号',max_length=11)
    # authors = models.OneToOneField('Authors', on_delete=models.CASCADE,verbose_name='关联作者')
    class Meta:
        verbose_name_plural = '作者详情'

    def __str__(self):
        return self.mobile

对于共有的字段我们可以创建一个基类,然后每一个表继承基类,这个基类是抽象的,目的是提供共有的字段,我们展示前端上面的删除,只是逻辑上的删除,后台并不会删除,这个事不会完成数据迁移的,abstract = True 不在数据库中建表,这样可以

 二、表断关联
 1、表之间没有外键关联,但是有外键逻辑关联(有充当外键的字段)
 2、断关联后不会影响数据库查询效率,但是会极大提高数据库增删改效率(不影响增删改查操作)
 3、断关联一定要通过逻辑保证表之间数据的安全,不要出现脏数据,代码控制
 4、断关联
 5、级联关系
       作者没了,详情也没:on_delete=models.CASCADE
       出版社没了,书还是那个出版社出版:on_delete=models.DO_NOTHING
       部门没了,员工没有部门(空不能):null=True, on_delete=models.SET_NULL
       部门没了,员工进入默认部门(默认值):default=0, on_delete=models.SET_DEFAULT

单查和群查


class BookGenericAPIView(GenericAPIView):
    queryset = Book.objects.all().filter(is_delete=False)
    serializer_class = BookModelSerializer

    def get(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        if pk:
            obj = Book.objects.filter(is_delete=False, pk=pk).first()
            serializer =self.get_serializer(instance=obj)
            return APIResponse(result=serializer.data)

        else:
            book_list = self.get_queryset()
            book_list = self.get_serializer(book_list, many=True)
            return APIResponse('100', '成功', data=book_list.data)

单增和群增


    def post(self, request, *args, **kwargs):
        if isinstance(request.data,dict):
            book_ser = self.get_serializer(data=request.data)  # 现在这个book_ser 是ListSerializer对象
            book_ser.is_valid(raise_exception=True)
            book_ser.save()
            return APIResponse('100','成功',book_ser.data)

        else:
            book_ser = self.get_serializer(data=request.data,many=True)
            book_ser.is_valid(raise_exception=True)
            book_ser.save()
            return APIResponse('100', '成功', book_ser.data)
  • 这里我们区别单增和群增:request.data是{},群增是[]
  • 在校验的时候我们捕获异常,失败就抛出异常,返回给前端

单改和群改

   def put(self, request, *args, **kwargs):
        if kwargs.get('pk',None):
            book = Book.objects.filter(pk=kwargs.get('pk')).first()
            book_ser = BookModelSerializer(instance=book, data=request.data, partial=True)  # 增多条
            book_ser.is_valid(raise_exception=True)
            book_ser.save()
            return Response(book_ser.data)

        else:
            # print(request.data)
            book_obj = [] # 存放当前书的对象
            book_list = []
            for item in request.data:
                book = Book.objects.filter(pk=item.pop('id'),is_delete=False).first()
                book_obj.append(book)
                book_list.append(item)

            book_ser = self.get_serializer(instance=book_obj,data=book_list,many=True)
            book_ser.is_valid(raise_exception=True)
            book_ser.save()
            return APIResponse('100', '成功', book_ser.data)

单整体该改分析整体该改分析

单整体改:接口:api/books/pk 数据:dict
1 分析request.data数据[{'pk':1,'name':'',publish:1,'authors':[1,2]}]
2 我们还可以从request.data中分离出数据,放在一个列表里面pks
3 pks中存放的pks在数据库中没有对应的数据,或者对应的数据已经删除,这些不合理的pk要剔除
4 pks最终转化得到的列表长度和request.data列表长度一致,否则就是数据有误
5 我们新增的数据使用的是ListSerializer--》create方法
		def create(self, validated_data):
               self.child是BookModelSerializer对象
               print(type(self.child))
                 return [
                     self.child.create(attrs) for attrs in validated_data
                 ]

单部修改和群修改

    def put(self, request, *args, **kwargs):
        if kwargs.get('pk',None):
            book = Book.objects.filter(pk=kwargs.get('pk')).first()
            book_ser = BookModelSerializer(instance=book, data=request.data, partial=True)  # 增多条
            book_ser.is_valid(raise_exception=True)
            book_ser.save()
            return Response(book_ser.data)

        else:
            # print(request.data)
            book_obj = [] # 存放当前书的对象
            book_list = []
            for item in request.data:
                book = Book.objects.filter(pk=item.pop('id'),is_delete=False).first()
                book_obj.append(book)
                book_list.append(item)

            book_ser = self.get_serializer(instance=book_obj,data=book_list,many=True)
            book_ser.is_valid(raise_exception=True)
            book_ser.save()
            return APIResponse('100', '成功', book_ser.data)

分析


    单整体改:接口:/books/(pk)/ 数据:dict
    群整体改:接口:/books/   数据:[{pk1, ...}, ..., {pkn, ...}] | {pks: [pk1, ..., pkn], data: [{}, ..., {}]}

这里的群改我们重新写update方法,因为我们最后用的序列化器是ListSerializer,这个没有写update方法

单删和群删


    def delete(self,request,*args,**kwargs):
        pk = kwargs.get('pk')
        pks = []
        if pk:
            pks.append(pk)
        else:
            pks = request.data.get('pks')
        res = Book.objects.filter(is_delete=False,pk__in=pks).update(is_delete=True) #把is_delete设置成true
        if res:
            return APIResponse(data={'msg': '删除成功'})
        else:
            return APIResponse(data={'msg': '没有要删除的数据'})

分析

单删和群删我们共用一个接口,无论是kwargs取过来的值,还是request.data取到的值,把单删的数据pk值放进pks=[]里面我们用一个删除的表

序列化的写法

from rest_framework import serializers
from app01.models import Publish,Book,Authors


class BookListSerializer(serializers.ListSerializer):
    def update(self, instance, validated_data):
        print(validated_data)

        # print(instance)
        return [
            self.child.update(instance[i],attrs) for i,attrs in enumerate(validated_data)
        ]




class BookModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        list_serializer_class = BookListSerializer
        fields = ["id", '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},
        }

分析重写的update

1 写一个类,继ListSerializer,重写update
2 self.child:是BookModelSerializer对象
3 self.child.update(对象,字典) for attrs in validated_data
4 和BookModelSerializer建立关联,list_serializer_class = BookListSerializer
posted @ 2020-07-19 23:23  小子,你摊上事了  阅读(94)  评论(0编辑  收藏  举报