Django-rest Framework(五)

The top ten Interface done in order to better understand the view of the back of the class

1. (focus) of the secondary package the Response; APIResponse inheritance Custom Response, a method override ____init____

from rest_framework.response import Response  #导入Response类

class APIResponse(Response):  #继承Response类
    def __init__(self,status=0,msg='ok',results=None,http_status=None,headers=None,exception=None,**kwargs): #重写__init__方法
        data = {
            'status':status,
            'msg':msg
        }
        if results is not None:
            data['result'] = results

        data.update(**kwargs)   #接收其他多余参数
        # 再使用父类的__init__方法
        super().__i

2. (Normal) orm model table, a set of abstract classes True model, called a base class, this class model as a base class is designed to provide the public attributes (data migration will not participate in the base class)

class BaseModel(models.Model):   #继承基础模型类
    is_delete = models.BooleanField()  #创建公共属性
    create_time = models.DateTimeField(auto_now_add=True)  #创建公共属性
    class Meta:
        abstract:True   # 声明为基类
        
class xxx(BaseModel)  # 其他类继承基类
    

3. (focus) ORM multi-table related operation (in book publishing tables of table table table, for example of the details):

  1. Foreign key release position

    1. Many: that a foreign key in a multi-party (press, books)

      class Book(BaseModel):
          name = models.CharField(max_length=32)
          price = models.DecimalField(max_digits=9,decimal_places=2)
          '''
               related_name='books' : 设置反向查询为books
               db_constraint=False : 断开外键约束
               on_delete=models.DO_NOTHING(在外键数据没有的情况下,任然保持数据 出版社没了,书还是       那个出版社出版)
          ''' publish=models.ForeignKey(to='Publish',related_name='books',db_constraint=False,on_delete=models.DO_NOTHING)
          # 多对多字段 断约束  设置反向查询名字
          author = models.ManyToManyField(to='Author',db_constraint=False,related_name='books')
      
      class Publish(BaseModel):
          name = models.CharField(max_length=32)
          addres = models.CharField(max_length=32)
    2. Many to many: foreign key on the popular party (book author)

      class Book(BaseModel):
          name = models.CharField(max_length=32)
          price = models.DecimalField(max_digits=9,decimal_places=2)
          '''
               related_name='books' : 设置反向查询为books
               db_constraint=False : 断开外键约束
               on_delete=models.DO_NOTHING(在外键数据没有的情况下,任然保持数据 出版社没了,书还是那个出版社出版)
          '''
          publish =                                     models.ForeignKey(to='Publish',related_name='books',db_constraint=False,on_delete=models.DO_NOTHING)
          # 多对多字段 断约束  设置反向查询名字
      author=models.ManyToManyField(to='Author',db_constraint=False,related_name='books')
      

    3. One to One: foreign key is not long on that party with

    class Book(BaseModel):
        name = models.CharField(max_length=32)
        price = models.DecimalField(max_digits=9,decimal_places=2)
        '''
             related_name='books' : 设置反向查询为books
             db_constraint=False : 断开外键约束
             on_delete=models.DO_NOTHING(在外键数据没有的情况下,任然保持数据 出版社没了,书还是那个          出版社出版)
        '''
        publish = models.ForeignKey(to='Publish',related_name='books',db_constraint=False,on_delete=models.DO_NOTHING)
        # 多对多字段 断约束  设置反向查询名字
        author = models.ManyToManyField(to='Author',db_constraint=False,related_name='books')
    
    
    Foreign key columns to forward the query field, related_name a reverse lookup field

2. How to break foreign key

Foreign key field db_constraint = False

3. Cascade relationship between foreign key

  1. One: not the author, the details are gone: on_delete = models.CASEADE
  2. Many: Press did not, or that book published by: on_delete = models.DO_ONTHING
  3. Many: Department did not, no department employees (empty department): null = True, on_delete = models.SET_NULL
  4. Many: Department did not, and department staff to enter the default (default value): default = 0, on_delete = models.SET_DEFAULT
  5. Many to many: You can not set on_delete

4. (Key) table even serialized, serialization method defined plug property class model, the query completion table even

    @property
    def author_detail(self):
        author_queryset = self.authors.all()   #查询出所有的作者
        author_detail = []
        for author_obj in author_queryset:
            author_detail.append(
                {
                    'name': author_obj.name,
                    'sex':author_obj.get_sex_display(),
                    'mobile':author_obj.detail.mobile

                }
            )
        return author_detail  #返回作者列表信息

The (normal) sequence may facilitate fast implementation of custom serialization depth foreign key, but not complete deserialization


# 前提 : 如果只有查需求的接口,自定义深度还可以用子序列化方式完成
class PublishSerilizer(ModelSerializer):
    # 子序列化都是提供外键(正方向)完成深度查询的,外键数据是唯一:many=Falise 不唯一 many=True
    #注 : 只能参与序列化,且反序列化不能写(反序列化外键字段会抛异常)
    books = BookSerializer(many=True)
    class Meta:
        model = models.Publish
        fields = ['name','address','books']

6. (important) single-cluster search check interface class provides the sequence of a serialized object, the data MANY parameters control the operation of one or a plurality of

7. (Normal) delete a single group delete interface field to remove background operation, a single front end provided pk delete, delete group is provided pks

# 单删 群删
    def delete(self,request,*args,**kwargs):
        pk = kwargs.get('pk')
        if pk:
            pks = [pk]
        else:
            pks = request.data.get('pks')
        row = models.Book.objects.filter(is_delete=False,pk__in=pks).update(is_delete=True)
        if row:
            return APIResponse.APIResponse(msg='delete ok')
        return APIResponse.APIResponse(status=1,msg='delete error')

8. (focus) by a single group by an interface, the data is determined by a single or by group, to the corresponding class settings MANY sequence, and the sequence of data can be only through

# 单增 群增
    def post(self,request,*args,**kwargs):
        request_data = request.data
        if isinstance(request_data,dict)  and len(request_data) !=0:
            book_ser = Serializers.BookSerializer(data=request_data,many=False)
            if book_ser.is_valid(raise_exception=True):
                book_obj = book_ser.save()
                return APIResponse.APIResponse(results=Serializers.BookSerializer(book_obj,many=False).data)
            else:
                return APIResponse.APIResponse(results=book_ser.errors)

        elif isinstance(request_data,list) and len(request_data) !=0:
            book_ser = Serializers.BookSerializer(data=request_data, many=True)
            if book_ser.is_valid(raise_exception=True):
                book_obj_list = book_ser.save()
                return APIResponse.APIResponse(results=Serializers.BookSerializer(book_obj_list,many=True).data)
            else:
                return APIResponse.APIResponse(results=book_ser.errors)
        else:
            return APIResponse.APIResponse(1,'add error')

9. (normal) single integral whole group modified to change the data provided by the front end, to be converted to the background objects are to be modified and updated data are used, ModelSerializser provided list_serializesr_class their associated ListSerializer, re-update () method, to complete the group that

# 单整体改  群整体改
    def put(self,request,*args,**kwargs):
        request_data = request.data
        pk = kwargs.get('pk')
        if pk:
            try:
                book_obj = models.Book.objects.get(pk=pk)
                print(pk)
                print(book_obj)
            except:
                return APIResponse.APIResponse(1,'update error')
            book_ser = Serializers.BookSerializer(instance=book_obj,data=request_data)
            book_ser.is_valid(raise_exception=True)
            res_obj = book_ser.save()
            return APIResponse.APIResponse(results=Serializers.BookSerializer(res_obj).data)
        elif isinstance(request_data,list) and len(request_data) !=0:
            obj_list = []
            data_list = []
            for dic in request_data:
                try:
                    pk = dic.pop('pk')
                    try:
                        obj = models.Book.objects.filter(pk=pk).first()
                        obj_list.append(obj)
                        data_list.append(dic)
                    except:
                        pass
                except:
                    return APIResponse.APIResponse(1,'update error')

            book_ser_list = Serializers.BookSerializer(instance=obj_list,data=data_list,many=True)
            book_ser_list.is_valid(raise_exception=True)
            book_res_list = book_ser_list.save()
            return APIResponse.APIResponse(results=Serializers.BookSerializer(book_res_list,many=True).data)
        else:
            return APIResponse.APIResponse(http_status=400,status=1,msg='update error')

10. (normal) single locally modified, serializing a modified object instance = parameter, data = modified data, partial = energy can locally modify the overall change is the single partial = False (default is False)

# 单局部改  群局部改
    def patch(self, request, *args, **kwargs):
        request_data = request.data
        pk = kwargs.get('pk')
        if pk:
            try:
                book_obj = models.Book.objects.get(pk=pk)
            except:
                return APIResponse.APIResponse(1, 'update error')
            book_ser = Serializers.BookSerializer(instance=book_obj, data=request_data,partial=True)
            book_ser.is_valid(raise_exception=True)
            res_obj = book_ser.save()
            return APIResponse.APIResponse(results=Serializers.BookSerializer(res_obj).data)
        elif isinstance(request_data, list) and len(request_data) != 0:
            obj_list = []
            data_list = []
            for dic in request_data:
                try:
                    pk = dic.pop('pk')
                    try:
                        obj = models.Book.objects.filter(pk=pk).first()
                        obj_list.append(obj)
                        data_list.append(dic)
                    except:
                        pass
                except:
                    return APIResponse.APIResponse(1, 'update error')

            book_ser_list = Serializers.BookSerializer(instance=obj_list, data=data_list, many=True,partial=True)
            book_ser_list.is_valid(raise_exception=True)
            book_res_list = book_ser_list.save()
            return APIResponse.APIResponse(results=Serializers.BookSerializer(book_res_list, many=True).data)
        else:
            return APIResponse.APIResponse(http_status=400, status=1, msg='update error')

Abnormal module code:


from rest_framework.response import Response  #导入Response类

class APIResponse(Response):  #继承Response类
    def __init__(self,status=0,msg='ok',results=None,http_status=None,headers=None,exception=None,**kwargs): #重写__init__方法
        data = {
            'status':status,
            'msg':msg
        }
        if results is not None:
            data['result'] = results

        data.update(**kwargs)   #接收其他多余参数
        # 再使用父类的__init__方法
        super().__init__(data=data,status=http_status,headers=headers,exception=exception)

orm models Code:

from django.db import models
from django.conf import settings


# 一、基表
# Model类的内部配置Meta类要设置abstract=True,这样的Model类就是用来作为基表
# 多表:Book,Publish,Author,AuthorDetail
class BaseModel(models.Model):
    is_delete = models.BooleanField(default=False)
    create_time = models.DateTimeField(auto_now_add=True)
    class Meta:
        # 基表必须设置abstract,基表就是给普通Model类继承使用的,设置了abstract就不会完成数据库迁移完成建表
        abstract = True

class Book(BaseModel):
    name = models.CharField(max_length=16)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish = models.ForeignKey(to='Publish', related_name='books', 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 author_detail(self):
        author_queryset = self.authors.all()
        author_detail = []
        for author_obj in author_queryset:
            author_detail.append(
                {
                    'name': author_obj.name,
                    'sex':author_obj.get_sex_display(),
                    'mobile':author_obj.detail.mobile

                }
            )
        return author_detail
    class Meta:
        verbose_name_plural = '书籍表'

    def __str__(self):
        return self.name


class Publish(BaseModel):
    name = models.CharField(max_length=16)
    address = models.CharField(max_length=64)

    class Meta:
        verbose_name_plural = '出版社表'

    def __str__(self):
        return self.name

class Author(BaseModel):
    name = models.CharField(max_length=16)
    sex = models.IntegerField(choices=[(0, '男'),(1, '女')], default=0)

    class Meta:
        verbose_name_plural='作者表'

    def __str__(self):
        return self.name

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)


The sequence code:

from rest_framework import serializers
from rest_framework.serializers import ModelSerializer
from . import models

class BookListSerializer(serializers.ListSerializer):

    def update(self, instance, validated_data):
        return [
            self.child.update(instance[i],attrs) for i,attrs in validated_data
        ]

class BookSerializer(ModelSerializer):
    class Meta:
        model = models.Book
        list_serializes_class = BookListSerializer
        fields = ['name','price','author_detail','publish','authors']
        extra_kwargs = {
            'publish':{
                'write_only':True
            },
            'authors':{
                'write_only':True
            }
        }

class PublishSerilizer(ModelSerializer):
    books = BookSerializer(many=True)
    class Meta:
        model = models.Publish
        fields = ['name','address','books']

Guess you like

Origin www.cnblogs.com/kuck/p/11921937.html