zoukankan      html  css  js  c++  java
  • 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 = True
    
    
    class 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 admin
    from app01 import models
    
    admin.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 models
    from rest_framework import serializers
    
    class 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 Response
    
    class 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_handler
    
    
    def 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 serializer
    from app01 import models
    from rest_framework.views import APIView
    from app01.utils import APIResponse
    
    
    class 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 admin
    from django.urls import path
    from app01 import views
    
    urlpatterns = [
        ### book表
        path('books/', views.BookView.as_view()),
        re_path('books/(?P<pk>d+)', views.BookView.as_view()),
    
    ]
  • 相关阅读:
    C#练习记录(统计字符串中的字符数和计算最大值)
    C#练习记录(交换两个数)
    Cyberdebut's daily record_3
    SWJTU_LightMoon Training #16~20 补题
    zzh训练日志3
    SWJTU_LightMoon Training #11~15 补题
    Megumin's daily record3
    2017网络赛
    zzh的训练日志2
    Cyberdebut's daily record_2
  • 原文地址:https://www.cnblogs.com/guojieying/p/13969245.html
Copyright © 2011-2022 走看看