IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> ORM配合DRF序列化组件使用 -> 正文阅读

[Python知识库]ORM配合DRF序列化组件使用

ORM配合DRF序列化组件使用

ORM建表操作补充

同一表不能有两个自增

class BaseModel(models.Model):
    is_delete = models.BooleanField(default=False)
    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
        

help_text : 写提示信息
models.CharField(max_length=32, verbose_name='书名',help_text='提示信息')

class Meta:
    verbose_name_plural = '书籍表'  # admin后台管理中显示表名
    
publish = models.ForeignKey(to='Publish',on_delete=models.CASCADE,db_constraint=True)    
on_delete:  models.CASCADE级联删除    models.DO_NOTHING啥也不做
db_constraint: True 在数据库中不建立实际的表关联,但是ORM语句可以正常用 能优化数据库
    
djangoadmin后台管理需要在admin中注册    
    admin.site.register(models.Book)
    admin.site.register(models.Publish)
    admin.site.register(models.Author)
    admin.site.register(models.AuthorDetail)

    
models.py中写方法,用于跨表查询是展示数据  
@property
def publish_name(self):
    return self.publish.name

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

ORM 增删查改实操核心源码

models.py

class BaseModel(models.Model):
    is_delete = models.BooleanField(default=False, verbose_name="是否删除")
    create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    last_update_time = models.DateTimeField(auto_now=True, verbose_name="修改时间")

    # 第二种写法
    # import datetime
    # create_time = models.DateTimeField(default=datetime.datetime.now)
    class Meta:
        # 抽象表,不在数据库中建表
        abstract = True


class Book(BaseModel):
    name = models.CharField(max_length=32, verbose_name='书名', help_text='提示信息')
    price = models.DecimalField(max_digits=8, decimal_places=2, verbose_name='价格')
    publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE, db_constraint=True, verbose_name='出版社')

    authors = models.ManyToManyField(to='Author', db_constraint=True, verbose_name='作者')

    class Meta:
        verbose_name_plural = '书籍表'  # admin后台管理中显示表名

    def __str__(self):
        return self.name  # 在admin后台管理上显示书名

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

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


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 Author(BaseModel):
    name = models.CharField(max_length=32, verbose_name='作者名')
    sex = models.IntegerField(choices=((1, '男'), (0, '女')), verbose_name='性别')
    authordetail = models.OneToOneField(to='AuthorDetail', db_constraint=True, on_delete=models.CASCADE,
                                        verbose_name='作者详情')

    class Meta:
        verbose_name_plural = '作者表'

    def __str__(self):
        return self.name


class AuthorDetail(BaseModel):
    phone = models.CharField(max_length=11)

    class Meta:
        verbose_name_plural = '作者详情表'

    def __str__(self):
        return self.phone

views.py
APIView和GenericAPIView和子类怎么选

  • GenericAPIView优先级高
# 基于APIView
class BookAPIView(APIView):
    def get(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        # 查一个
        if pk:
            book = models.Book.objects.filter(pk=pk).first()
            if book:
                book_ser = ser.BookModelSerializer(book)
                return APIResponse(data=book_ser.data)
            return APIResponse(code=102, msg='该数据不存在')
        # 查询所有
        book_list = models.Book.objects.all().filter(is_delete=False)
        book_list_ser = ser.BookModelSerializer(book_list, many=True)

        return Response(data=book_list_ser.data)

    def post(self, request, *args, **kwargs):
        #  增单条
        if isinstance(request.data, dict):
            book_ser = ser.BookModelSerializer(data=request.data)
            book_ser.is_valid(raise_exception=True)
            book_ser.save()
            # 增多条
        elif isinstance(request.data, list):
            book_ser = ser.BookModelSerializer(data=request.data, many=True)
            # 现在book_ser 是 ListSerializer对象
            book_ser.is_valid(raise_exception=True)
            book_ser.save()
            '''
            新增---》ListSerializer--》ListSerializer的create方法
            源码:
            def create(self, validated_data):
                # self.child是BookModelSerializer对象
                return [
                     self.child.create(attrs) for attrs in validated_data
                ]
            '''
        else:
            return APIResponse(code=102, msg='未知错误')
        return APIResponse(data=book_ser.data)

    def put(self, request, *args, **kwargs):
        if kwargs.get('pk'):
            book = models.Book.objects.filter(pk=kwargs.get('pk')).first()
            if book:
                # partial=True 允许部分修改,相当于在每个字段都加了一个required=False
                book_ser = ser.BookModelSerializer(instance=book, data=request.data, partial=True)
                # 校验数据是否合法
                book_ser.is_valid(raise_exception=True)
                book_ser.save()
                return APIResponse(data=book_ser.data)
            return APIResponse(code=102, msg=f'id值为:`{kwargs.get("pk")}`数据不存在')
        book_list = []
        modify_data = []
        error_list = []
        for item in request.data:
            pk = item.get('id')
            book = models.Book.objects.filter(pk=pk).first()
            if book:
                item.pop('id')
                book_list.append(book)
                modify_data.append(item)
            else:
                error_list.append(item)
        # 方案1 for 循环一个个修改,核心点
        # for i,si_data in enumerate(modify_data):
        #     book_ser = ser.BookModelSerializer(instance=book_list[i], data=si_data)
        #     book_ser.is_valid(raise_exception=True)
        #     book_ser.save()
        # return Response(data='成功')
        # 方案2 重写ListSerializer的update方法  推荐使用
        book_ser = ser.BookModelSerializer(instance=book_list, data=modify_data, many=True, partial=True)
        book_ser.is_valid(raise_exception=True)
        book_ser.save()
        if error_list:
            return APIResponse(code=103, msg='部分信息修改成功', data=book_ser.data,
                               error={"msg": "下述id值信息不存在", "data": [data for data in error_list]})
        return APIResponse(data=book_ser.data)

    def delete(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        pks = []
        if pk:
            # 单条删除
            pks.append(pk)
        else:
            # 多条删除,前端给数据
            # {'pks':[1,2,3]}
            pks = request.data.get('pks')
            # 把is_delete设置成true
            # ret返回受影响的行数
        ret = models.Book.objects.filter(pk__in=pks, is_delete=False).update(is_delete=True)
        if ret:
            return Response(data={'msg': '删除成功'})
        else:
            return Response(data={'msg': '没有要删除的数据'})

# 基于GenericAPIView
class BookGenericAPIView(GenericAPIView):
    queryset = models.Book.objects.filter(is_delete=False).all()
    serializer_class = ser.BookModelSerializer

    def get(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        if pk:
            book = self.get_object()
            if book:
                book_ser = self.get_serializer(book)
                return APIResponse(data=book_ser.data)
            return APIResponse(code=102, msg='该数据不存在')
        book_list = self.get_queryset()
        book_list_ser = self.get_serializer(book_list, many=True)
        return APIResponse(data=book_list_ser.data)

    def post(self, request, *args, **kwargs):
        #  增单条
        if isinstance(request.data, dict):
            book_ser = self.get_serializer(data=request.data)
            book_ser.is_valid(raise_exception=True)
            book_ser.save()
            # 增多条
        elif isinstance(request.data, list):
            book_ser = self.get_serializer(data=request.data, many=True)
            # 现在book_ser 是 ListSerializer对象
            book_ser.is_valid(raise_exception=True)
            book_ser.save()
        else:
            return APIResponse(code=102, msg='未知错误')
        return APIResponse(data=book_ser.data)

    def put(self, request, *args, **kwargs):
        if kwargs.get('pk'):
            book = self.get_object()
            if book:
                # partial=True 允许部分修改,相当于在每个字段都加了一个required=False
                book_ser = self.get_serializer(instance=book, data=request.data, partial=True)
                # 校验数据是否合法
                book_ser.is_valid(raise_exception=True)
                book_ser.save()
                return APIResponse(data=book_ser.data)
            return APIResponse(code=102, msg=f'id值为:`{kwargs.get("pk")}`数据不存在')
        book_list = []
        modify_data = []
        error_list = []
        for item in request.data:
            pk = item.get('id')
            book = models.Book.objects.filter(pk=pk).first()
            if book:
                item.pop('id')
                book_list.append(book)
                modify_data.append(item)
            else:
                error_list.append(item)
        book_ser = self.get_serializer(instance=book_list, data=modify_data, many=True, partial=True)
        book_ser.is_valid(raise_exception=True)
        book_ser.save()
        if error_list:
            return APIResponse(code=103, msg='部分信息修改成功', data=book_ser.data,
                               error={"msg": "下述id值信息不存在", "data": [data for data in error_list]})
        return APIResponse(data=book_ser.data)

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

序列化操作补充

Serializer和ModelSerializer选择

  • 如果序列化是数据表,尽量使用ModelSerializer

ser.py

# 写一个类,继承ListSerializer,重写update方法实现批量修改
class BookListSerializer(serializers.ListSerializer):
    def update(self, instance, validated_data):
        # 保存数据
        # self.child:是BookModelSerializer对象
        # ll=[]
        # for i,si_data in enumerate(validated_data):
        #     ret=self.child.update(instance[i],si_data)
        #     ll.append(ret)
        # return ll
        return [
            self.child.update(instance[i], attrs) for i, attrs in enumerate(validated_data)
        ]

class BookModelSerializer(serializers.ModelSerializer):
    # 外键字段展示方案一(序列化没问题,反序列化有问题)
    # publish = serializers.CharField(source='publish.name')

    # 第二种方法,在models中写方法
    class Meta:
        # 批量增和批量改时,调用自己写的BookListSerializer
        list_serializer_class = BookListSerializer
        model = models.Book
        # fields = '__all__'
        # depth = 1   # 展示数据深度,不常用
        fields = ('id', 'name', 'price', 'authors', 'publish', 'publish_name', 'author_list')
        extra_kwargs = {
            'publish': {'write_only': True},
            'publish_name': {'read_only': True},
            'id': {'read_only': True},
            'authors': {'write_only': True},
            'author_list': {'read_only': True},
        }
  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-03-15 22:28:05  更:2022-03-15 22:29:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 20:30:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码