django - 将类的属性转换为 django 模型子类
问题描述
我有一堆类,我现在正试图将它们合并到django
.
例如,我有一个Base
类,我的所有其他类都派生自:
class Base:
def __init__(self, label: str = 'Base'):
self.label = label
sublcas 的一个例子是一个Person
类:
from typing import Any, Dict
class Person(Base):
def __init__(self, name: str, attributes_to_options: Dict[str, Any], **kwargs):
super().__init__(**kwargs)
self.name = name
self.attributes_to_options = attributes_to_options
我将其用作:
alex = Person(name='Alex', attributes_to_options={'age': 10, 'is_happy': True}, label='Person:Alex')
我的问题是,我如何将这样的课程纳入django
?它像继承一样简单models.Model
吗?例如
from django.db import models
class Person(Base, models.Model):
def __init__(self, name: str, attributes_to_options: Dict[str, Any], **kwargs):
super().__init__(**kwargs)
self.name = name
self.attributes_to_options = attributes_to_options
但是,我该如何models.CharField
为这两个属性指定name
和attributes_to_options
?
感谢您在这里的任何帮助。
解决方案
请记住,一般来说,任何 DjangoModel
子类都对应一个数据库表。从这样的类继承(“具体继承”)意味着将创建另一个数据库表,并在行之间建立一对一的链接,并且每个查询都将隐式地在数据库中执行连接。这对性能不利。但是对于行数不多的表或不经常查询的表,您可能不需要关心。
Django 提供了两种特殊情况,可以通过子Meta
类中的Model
类来定义。第一个是“抽象基类”,它允许您定义一堆将出现在任何派生模型中的东西。在字段的情况下,它们被“复制”到继承它们的类中,而不是拥有自己的数据库表。第二个是“代理”类,它允许您在现有数据库表的顶部放置一组新方法,这在某种程度上允许多态模型。仔细阅读 Django 文档。是个好主意。
我已经通过实验确定,人们也可以使用混合类,就像使用基于类的视图一样。换句话说,
class ExtraMethodsMixin( object): # NB must inherit from object
# NB no model field definitions allowed here
@property
def something_or_other(self):
return something_based_on_model_fields_defined_elsewhere
#etc.
接着
class Foo( ExtraMethodsMixin, models.Model): # NB mixin goes first
# define names and fields that the ExtraMethodsMixin uses
# (and anything else that a Foo needs)
...
我发现的一个问题是迁移确实记住了 on 的依赖,Foo
因此 ExtraMethodsMixin
如果您希望在以后完全删除 mixin,它是一个 PITA。但是,您可以将它存入单个pass
语句而不会出现任何问题,因此这可能不是一个大问题。我的另一个担心是这种用法完全没有记录(除了作为标准 Python 之外),所以它很可能以我尚未发现的一些非常微妙的方式践踏 Django 内部。所以我肯定有点缺乏推荐这种技术。
推荐阅读
- php - PHP 在 PHPMailer 中报告“无法重新声明类”
- php - 致命错误:允许的内存大小为 268435456 字节已用尽(尝试分配 8192 字节)
- asp.net-mvc - Sitefinity 更改已发布但无法在浏览器中运行
- hibernate - 对于 DDL,ElementCollection 中的 Embeddable 中的约束被忽略
- c++ - 一个类可以包含一个后来专门用于派生类的基类作为成员吗?
- kotlin - 如何在返回 Deferred 的异步函数中延迟
- lua - 使用 Lua 脚本避免宏病毒行为?
- python - Numpy arcsinh np.arcsinh() 转换函数的比例参数
- botframework - Oauth 登录不起作用,显示:['application/vnd.microsoft.card.oauth' 类型的文件]
- ruby-on-rails - 关系数据库和外键