社区首页 >问答首页 >Django动态生成序列化程序

Django动态生成序列化程序
EN

Stack Overflow用户
提问于 2020-11-12 11:11:12
回答 2查看 946关注 0票数 1

有办法动态生成Django rest框架序列化器吗?

考虑到这一点:

代码语言:javascript
代码运行次数:0
复制
    class BlogSerializer(serializers.ModelSerializer):
    
        class Meta:
            model = models.Blog
            fields = get_all_model_fields(models.Blog)
    
    class PostSerializer(serializers.ModelSerializer):
    
        class Meta:
            model = models.Post
            fields = get_all_model_fields(models.Post)
     
    
    class UserSerializer(serializers.ModelSerializer):
    
        class Meta:
            model = models.User
            fields = get_all_model_fields(models.User)

我想知道是否可以像下面这样的例子:

代码语言:javascript
代码运行次数:0
复制
from django.apps import apps

models = [model for model in apps.get_models()]

for model in models:
    type(model.__name__+'Serializer',(serializers.ModelSerializer,),{
       type("Meta",(),{
           "model":model,
           "fields": get_all_model_fields(model)
       })
    })

或者有没有其他方法来生成DRF串行化器?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-04-24 22:11:13

下面是为给定的ModelSerializer构建Model的函数(用Django 3.2、DRF 3.12.4和Python3.8进行测试):

代码语言:javascript
代码运行次数:0
复制
from functools import lru_cache
from typing import Type

from django.db import models
from rest_framework import serializers

@lru_cache(maxsize=0)
def model_serializer(model: Type[models.Model]) -> Type[serializers.ModelSerializer]:
    meta_class = types.new_class("Meta")
    setattr(meta_class, "model", model)
    setattr(meta_class, "fields", "__all__")
    result = types.new_class(
        model.__name__ + "Serializer", (serializers.ModelSerializer,), {}
    )
    setattr(result, "Meta", meta_class)
    return result

如果您确信只对每个序列化程序调用该函数一次,则可以省略缓存以保留一些内存。

示例用法:

代码语言:javascript
代码运行次数:0
复制
class MyModel(models.Model):
    some = models.CharField(max_length=123)
    other = models.IntegerField()

MyModelSerializer = model_serializer(MyModel)
my_serializer = MyModelSerializer({"some": "abc", "other": 1234})
my_serializer.is_valid(True)

若要将所有模型的序列化器添加到当前模块的命名空间,请执行以下操作:

代码语言:javascript
代码运行次数:0
复制
from django.apps import apps

for model in apps.get_models():
    serializer_type = model_serializer(model)
    globals()[serializer_type.__name__] = serializer_type
票数 2
EN

Stack Overflow用户

发布于 2020-11-12 13:05:22

您的方法是可行的,但是Django要想找到这些序列化器,就必须将它们分配给模块命名空间。

在您的代码中,只需调用type --将立即创建序列化程序类并“丢弃”。即使基本Django类serializers.ModelSerializer在注册表中保留了对它的引用,您也无法导入序列化程序并使用它们。

您所要做的就是将它们添加到globals()返回的字典中。类似地,您为该类创建的命名空间还必须是一个字典( -since ),您正在调用" type“,但实际上没有将它的名称指定为"Meta",而是创建了一个集合,而不是一个字典,您对类型的调用将失败,因为它期待一个字典。

因此,我没有检查代码是否实际工作,但基于您的想法是:

代码语言:javascript
代码运行次数:0
复制
from django.apps import apps

models = [model for model in apps.get_models()]

for model in models:
    name = f"{model.__name__}Serializer"
    globals()[name] =  type(name,(serializers.ModelSerializer,),{
       "Meta": type("Meta",(),{
           "model":model,
           "fields": get_all_model_fields(model)
       })
    })
del models, model, name
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64810287

复制
相关文章
输出9*9口诀
输出9*9口诀 //题目:输出9*9口诀。 #include int main() { int i,j,result; printf("\n"); for (i=1;i<10;i++) { //一排一排的打印! 举个例子:第一排打印1*1 第二排就打印 2*1 2*2 for(j=1;j<=i;j++) { result=i*j; printf("%d*%d=%-3d",i,j,
川川菜鸟
2021/10/18
4090
for循环输出杨辉三角
/** @author 葆宁 @time 2019.3.14 */ public class Example { public static void main(String[] args) { int triangle[][]=new int[8][];// 创建二维数组 // 遍历二维数组的第一层 for (int i = 0; i < triangle.length; i++) { triangle[i]=new int[i+1];// 初始化第二层数组的大小 // 遍历第二层数组
葆宁
2019/04/19
9550
for循环输出杨辉三角
输出三角形
题目:输出一个三角形 基本思想: 输出图形 首先要知道顶点个数, 然后要判断间隔,k<n-i 最后*的个数是2n-1个 代码实现: private static void triangle(int n) { for(int i=1;i<=n;i++) { for(int k=0;k<n-i;k++) { System.out.print(" "); } for(int j=1;j<=2*i-1;j++) { System.out.print("*"); } System.o
呆呆
2021/10/07
6100
C语言 | 输出杨辉三角
例26:C语言实现输出杨辉三角。 解题思路:对于这道题,小林拆分为3部分进行讲解 第一部分,对有特点的数(每行开头和结束的数都是1)进行赋值: for(i=0;i<10;i++)//for循环    {     array[i][i]=1;//给二维数组的每一行的最后一个赋值为1      array[i][0]=1;//第二维数组的每一行的开头赋值为1    } 第二部分,给中间的数进行赋值: for(i=2;i<10;i++)//外层循环限制行    {     for(j=1;j<=i-1;j++)/
小林C语言
2020/12/04
2.7K0
C语言 | 输出杨辉三角
tslint pre-commit 配置教程
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/j_bleach/article/details/78309599
j_bleach
2019/07/02
1.4K0
tslint pre-commit 配置教程
升级Gradle 3.0重命名Apk并输出指定目录
背景是工程之前用的2.2.2版本,gradle-wrapper是gradle-2.14.1-all,这个版本的重命名apk和输出指定目录如下代码:
巫山老妖
2019/03/04
1.3K0
升级Gradle 3.0重命名Apk并输出指定目录
java利用for循环输出正三角新解
本人在重新学习Java的过程中,遇到一个作业,就是用循环输出正三角,在完成作业之余,查看了很多网上的答案,用了好几次for循环,基本思路就是先拼接前面的空格,在去拼接后面的“”符号。感觉有点捉急,自己想了一想新的办法来更少的循环来得到答案。我利用一个if-else判断,以三角形顶点作为临界点,然后根据输出行数不同,拼接不同数量的空格和“”,分享代码,供大家参考。(一共两个例子,一个是正向的三角形,一个是等边三角形)
FunTester
2019/08/19
2.1K0
如何用C语言输出杨辉三角
题目描述:还记得中学时候学过的杨辉三角吗?具体的定义这里不再描述,你可以参考以下的图形:
小Bob来啦
2020/12/16
1.3K0
如何用C语言输出杨辉三角
C语言——输出9x9乘法表
九九乘法表是比较简单的程序,也是刚入门编程的同学一定会遇到的一个编程题,下面我就来给大家讲讲如何实现它
Gorit
2021/12/09
5600
C语言——输出9x9乘法表
输出杨辉三角(C++和 JAVA版 )
C++版本: #include using namespace std; void main() { int n=10; while(n!=-1) { cout<<"请输入 杨辉三角 行数:"; cin>>n; int **a = new int* [n]; for(int m = 0; m < n; m++) { a[m] = new int [n]; } for(int i=0;i 效果: JAVA版: import j
明明如月学长
2021/08/27
4470
C语言输出各种三角形
有些是有两种方法,一种是通过限制每行星星的个数进行输出,一种是根据数组下标进行输出。
全栈程序员站长
2022/09/15
1.1K0
C语言输出各种三角形
输出三角形【 Java 多线程 】
题目: 利用多线程输出两个三角形,要求控制两个线程的发生,判断第一个线程是否结束。 并且在第一个线程没结束时,使用 sleep 方法或者 join 方法。 1、sleep 方法。 public class Main { public static void main(String[] args) { Test m = new Test(); Thread t1 = new Thread(m, "T1"); Thread t2 = new Thread(m, "T2"); t
Lokinli
2023/03/09
3500
C++函数定义 | 输出有参无参
函上一节小林已经讲过,从函数形式来看,函数分为无参函数和有参函数,那么他们有什么不同呢?
小林C语言
2020/11/30
1.4K0
C++函数定义 | 输出有参无参
28-输出等腰三角形
思路 每行前输出空格的数量 每行空格后*的数量 每行后注意输出换行符 代码 #include <stdio.h> /* 本实例要求从键盘输入任意整数 n,通过程序运行输出对应高度为 n 的等腰三角形 */ void PrintTriangle(int n) { // 输出几行 for (int i = 0; i < n; i++) { // 输出每行前的空格 for (int j = 0; j < n - i -1; j++) {
lexingsen
2022/02/25
2970
练习2-3 输出倒三角图案 (5分)
本题要求编写程序,输出指定的由“*”组成的倒三角图案。 输入格式: 本题目没有输入。 输出格式: 按照下列格式输出由“*”组成的倒三角图案。 * * * * * * * * * * 思路分析: 本题目就是简单的入门,使用printf()函数在控制台打印字符串。 参考代码: #include<stdio.h> int main() { printf("* * * *\n"); printf(" * * *\n"); printf(" * *\n"); printf("
C you again
2021/02/24
9310
C语言数组例题:输出杨辉三角形
杨辉三角:是二项式系数在三角形中的一种几何排列,中国南宋数学家杨辉1261年所著的《详解九章算法》一书中出现。在欧洲,帕斯卡(1623----1662)在1654年发现这一规律,所以这个表又叫做帕斯卡三角形。帕斯卡的发现比杨辉要迟393年,比贾宪迟600年。
岳泽以
2022/10/26
1.1K0
C语言数组例题:输出杨辉三角形
java--第9章 输入输出流
1.编写一个程序将字符串“明月松间照,清泉石上流。”写入C:\a.txt中,并实现对该文件的读取。
北山啦
2022/11/27
3050
java--第9章   输入输出流
输出1234无重复三位数
有1,2,3,4四个数字求四个数字能生成多少个互不相同且无重复数字的三位数(不能含有122,133类似)
算法与编程之美
2021/12/15
6260
点击加载更多

相似问题

Linting不为tslint角9的打字本3.7工作

11

跳过tslint警告角

16

TSLint无引用规则替代

129

角JS路由无输出

26

错误无阴影变量- tslint错误

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文