Python 向Django模型中添加属性';s元类

Python 向Django模型中添加属性';s元类,python,django,django-models,metadata,Python,Django,Django Models,Metadata,我正在编写一个mixin,它可以让我的模型很容易地转换成一个深度的值(有点像.values(),但要遍历关系)。最干净的地方做这些定义似乎是在模型本身,洛杉矶: class Person(models.Model, DeepValues): name = models.CharField(blank=True, max_length=100) tribe = models.ForeignKey('Tribes') class Meta: schema =

我正在编写一个mixin,它可以让我的模型很容易地转换成一个深度的值(有点像.values(),但要遍历关系)。最干净的地方做这些定义似乎是在模型本身,洛杉矶:

class Person(models.Model, DeepValues):
    name = models.CharField(blank=True, max_length=100)
    tribe = models.ForeignKey('Tribes')

    class Meta:
        schema = {
            'name' : str,
            'tribe' : {
                'name' : str
            }
        }

Person.objects.all().deep_values() => {
    'name' : 'Andrey Fedorov',
    'tribe' : {
        'name' : 'Mohicans'
    }
}
然而,Django抱怨我在
类Meta
中包含了以下内容:

TypeError: 'class Meta' got invalid attribute(s): schema
(整个堆栈跟踪)


现在,我想我可以在我的mixin中仔细地覆盖它,但是有没有一种更优雅的方式来存储这些信息呢?

我不知道优雅,但一种实用的方式是:

import django.db.models.options as options

options.DEFAULT_NAMES = options.DEFAULT_NAMES + ('schema',)

显然,如果Django添加了自己的“schema”属性,那么这一点就会被打破。但是,这是一个想法……您可以选择一个不太可能冲突的属性名称。

这不是一个直接的答案,但我不喜欢将它添加到每个需要它的模型的选项中,所以我做了:

class MyModel(models.Model):
    
    class Meta:
        ordering = ["myfield"]

    class MyPrefixMeta:
        my_value = "Abc"

您甚至可以将其放在抽象模型中,并在
\uuuu init\uuuu
函数中验证所设置的类属性,或者执行类似于向模型添加
\umyprefix\umeta
属性的操作。所以您有了自己的元类。

这对我来说很有用,可以为Django模型在元中设置额外的字段

class Vendor(CustomModel):

    def __init__(self, *args, **kwargs):
        cls = self.__class__
        meta = getattr(cls, '_meta', None)
        setattr(meta, 'exclude_logging', ["otp", "is_otp_verified"])
        super().__init__(*args, **kwargs)
exclude_logging
字段可按如下方式访问

class CustomModel(models.Model):

    objects = UpdateManager()

    class Meta:
        abstract = True

    def save(self, *args, **kwargs):
        print(self._meta.exclude_logging)

我希望这能解决问题。

为了子孙后代,这不起作用,但确实起了作用:options.DEFAULT\u NAMES=options.DEFAULT\u NAMES+(“DEFAULT\u values”),哦。。。这大概是因为我的解决方案将默认的_名称转换为一个列表,而您的优化将其保留为一个元组。