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知识库 -> 关于外键关联的序列化/反序列化优化写法 -> 正文阅读

[Python知识库]关于外键关联的序列化/反序列化优化写法

学习了drf 的教程后,自己摸索和修改了一些关于模型外键关联的使用
一. 创建一个外键关联的模型类

from django.db import models

# Create your models here.

""" 一对多 等关系,  把 on_deelte 放在多的方向 """
class UserType(models.Model):
    caption = models.CharField(max_length=120)

class UserInfo(models.Model):
    user_type = models.ForeignKey(UserType, on_delete=models.CASCADE, related_name="Type")
    username = models.CharField(max_length=100)
    age = models.IntegerField()

二. 创建两个相对应的序列化类

from rest_framework import serializers
from .models import UserInfo, UserType


class TypeSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserType
        # 使用exclude 排除序列化 id 
        # fields = ["caption"]
        exclude  = ['id']


class InfoSerializer(serializers.ModelSerializer):
    user_type = TypeSerializer()

    class Meta:
        model = UserInfo
        fields = ["age", "username", "user_type"]

    """嵌套模型类 ,重写create方法 """
    def create(self, validated_data):
        """
        先创建主表,再创建次表
        """
        # 可以先查询是否已具有 caption 数据,有就直接使用,没有就创建
        # validated_data  为传入的数据
        type =  validated_data.pop("user_type")
        Ftype = type["caption"]

        otype = UserType.objects.filter(caption=Ftype)
        if otype.exists() == False:
            # 先创建 type表
            c1 = UserType.objects.create(**type)
        else:
            c1 = otype[0]
        # 在创建 info 表, 因为user是外键对象,所以需要 传入创建的 type对象
        c2 = UserInfo.objects.create(user_type=c1, **validated_data)
        return c2

    def update(self, instance, validated_data):
        """
        重写update方法
        """
        # 获取用户类型对象创建数据
        uType_data = validated_data.pop("user_type")
        
        # 需要判断新放入的usertype 是否是表中已有的数据, 没有就更换,已有就复用
        tyobjcet = UserType.objects.filter(caption =  uType_data.get("caption"))
        if tyobjcet.exists == False: # 数据为空就是进行更换操作
            type_object = instance.user_type
            # instance : 代表新建立的 object 
            instance.age = validated_data.get("age", instance.age)
            instance.username = validated_data.get("username", instance.username)   
            instance.save()
            type_object.caption = uType_data.get("caption", type_object.caption)   
            type_object.save()
        else:  # if userType 查询到对应数据,直接将其重新复用到 info 的user_type 属性上
            instance.user_type = tyobjcet[0]
            type_object = instance.user_type
            # instance : 代表新建立的 object 
            instance.age = validated_data.get("age", instance.age)
            instance.username = validated_data.get("username", instance.username)   
            instance.save()

        
        return instance

此处主要是在 modelSerilaizer下重写了 create() 与 Update()方法;
实列
在shell中使用create方法

from UserType.serializer import InfoSerializer,TypeSerializer
>>> data = {"age":26, "username":"testcreate","user_type":{"caption": "None"}} 
>>> ob = InfoSerializer(data=data)
>>> ob.is_valid()
True
>>> ob.save()
<UserInfo: UserInfo object (5)>
>>> ob.data
{'age': 26, 'username': 'testcreate', 'user_type': OrderedDict([('caption', 'None')])}
>>>

在shell中的使用update方法

>>> from UserType.serializer import InfoSerializer,TypeSerializer
>>> from UserType.models import  UserInfo, UserType
>>> data = {"age":26, "username":"testyjx+1","user_type":{"caption": "female"}}
>>> ob = UserInfo.objects.filter(pk=1)
>>> ob[0]
<UserInfo: UserInfo object (1)>
>>> da = InfoSerializer(ob[0], data=data) 
>>> da.is_valid()
True
>>> da.save()
<UserInfo: UserInfo object (1)>
>>> da.data
{'age': 26, 'username': 'testyjx+1', 'user_type': OrderedDict([('caption', 'female')])}

总结:
主要官方drf 教程中只有简单的使用,在API指南的使用也是比较单一的,create()与update()可以自定义diy;官方不支持自动处理多嵌套处理;有第三方库DRF Writable Nested支持;后续再写一篇关于DRF Writable Nested的使用

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-02-22 20:32:43  更:2022-02-22 20:35:00 
 
开发: 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/16 0:20:40-

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