惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Y
Y Combinator Blog
IT之家
IT之家
博客园_首页
人人都是产品经理
人人都是产品经理
博客园 - Franky
I
InfoQ
Recent Announcements
Recent Announcements
P
Proofpoint News Feed
H
Hackread – Cybersecurity News, Data Breaches, AI and More
GbyAI
GbyAI
大猫的无限游戏
大猫的无限游戏
aimingoo的专栏
aimingoo的专栏
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
月光博客
月光博客
Microsoft Security Blog
Microsoft Security Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
B
Blog RSS Feed
MongoDB | Blog
MongoDB | Blog
雷峰网
雷峰网
博客园 - 聂微东
N
Netflix TechBlog - Medium
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
The GitHub Blog
The GitHub Blog
D
Docker

Django

请教下 哪款 vscode 插件可以通过点击跳转 urls 定义 Django 一文告诉你 all 懒加载的机制 大家学习编程做项目的时候一开始会容易卡壳吗?比如我今天一个下午才弄出来了博客当中的文章评论加回复功能,有时候会因为一个小点卡壳,稍微复杂点的逻辑就感觉脑子不够用,甚至是给 html 的 div 取变量名的时候脑子也会不够 请教在 ubuntu23 中如何 让 Django runserver 开机自启动 请教 Django runserver 开机自启动的问题 不知道开发的流媒体合租平台有没有意义… 公司自主招聘(远程)后端 Go 开发,想要远程岗位抓紧啦 [求助] Mediacms 接入 Keycloak 有没有好的 drf 项目可以学习下的? django 快速开发明明 drf 更好,为啥还是很多人更推荐 fast.api 和忍者 django 的同步机制有性能瓶颈为什么还是有很多人用? 大家怎么处理开发时 Migration 一大堆,修修改改啰啰嗦嗦,同步到生产之前还得检查合并下这个问题的? Django 模型自定义 Manager 自定义 filter 如何支持链式调用? python3 manage.py build_index 这条 Django 命令到底啥意思啊?官方文档找不到说明,谢谢 前后端分离项目, Django 良好的项目结构是怎么样的 Django get_max_test_processes Django makemigrations 生成的 migrations 文件,如何放在代码当前目录的文件夹中? 请教下大家,Django 的 tests 测试模块,如何不创建新从测试数据库,而是直接操作生产环境数据库谢谢! django 好像对于 ios 打不开 admin page Django 模板中变量的嵌套 早起把网站的友链网页和自主添加友链功能撸出来了,过来收集一波友链 用 django 调用长时间执行的脚本,如何返还输出呢? Django 中递归分类 model 用什么组件显示比较合适? django 一开始没用 restfulapi 开发, 还能自动生成文档吗? 求推 django 数据可视化插件 django 用 docker 部署,要不要每次部署到服务器的时候改改 image 的 settings 配置 有没有使用 django 国际化模块的,针对 django.po 国际化文件写了一个 vscode 的插件 Django 访问 relation 时,如何得知是谁访问的? django admin 部分自带的 css 文件 collectstatic,生成的文件大小为 0? Django 怎么做同一个 url,对应不同的 view 函数?
分享一个在 Django 的 model 里,使用元类动态添加相似的带自...
firejoke · 2021-11-05 · via Django

当有多个 model 通过 ManyToManyField 关联到同一个目标 model 时,如果这个 ManyToManyField 需要额外的字段,则需要单独定义一个中间表。
这时中间表除了指向的源表是不一样的,其他字段包括目标表都是一样的,比如:

# base model
class Created(models.Model):
    created = models.DateTimeField(auto_now_add=True)

    class Meta:
        abstract = True
        required_db_vendor = "postgresql"


class CreatedModified(Created):
    last = models.DateTimeField(auto_now=True)

    class Meta(Created.Meta):
        abstract = True
class Argument(CreatedModified):
    ...


class ArgumentThrough(CreatedModified):
	# argument 中间表基类
    argument = models.ForeignKey(
        to=Argument,
        on_delete=models.PROTECT
    )
    value = models.JSONField(blank=True)

    def clean(self):
        argument_value_validator(self.argument, self.value)

    class Meta(CreatedModified.Meta):
        abstract = True

class Inventory(CreatedModified):
    ...

    class Meta(CreatedModified.Meta):
        abstract = True


class Host(Inventory):
    inventory_variables = models.ManyToManyField(
        to=Argument,
        through="HostArgument",
        blank=True,
        help_text=_("Variables for host")
    )


class HostArgument(ArgumentThrough):
    # Host 到 Argument 的中间表
    host = models.ForeignKey(
        to=Host,
        on_delete=models.CASCADE
    )


class Group(Inventory):
    inventory_variables = models.ManyToManyField(
        to=Argument,
        through="GroupArgument",
        blank=True,
        help_text=_("Variables for group")
    )



class GroupArgument(ArgumentThrough):
    # Group 到 Argument 的中间表
    group = models.ForeignKey(
        to=Group,
        on_delete=models.CASCADE
    )

可以看到 Host 和 Group 的两个关联 Argument 的中间表除了指向的源表以外,其他字段几乎是一模一样的,所以可以改成这样:

class Host(Inventory):
    ...


class Group(Inventory):
    ...
 
 
 def add_related_field__argument(cls):
    through_cls_dict = {
        cls.__name__.lower(): models.ForeignKey(
            to=cls, on_delete=models.CASCADE
        ),
        "__module__": cls.__module__
    }

    cls.add_to_class(
        "inventory_variables", models.ManyToManyField(
            to=Argument,
            through=type(
                f"{cls.__name__}Argument", (ArgumentThrough,), through_cls_dict
            ),
            blank=True,
        )
    )


for model in (Host, Group):
    add_related_field__argument(model)

用这种方法,就可以不用写“重复”的代码了。
不知道你们是怎么解决这类问题的,希望我能抛砖引玉。