3

注意:这是在AbstractUser存在之前提出的,这可能是您现在想要使用的。

基本上我想从默认的 Django User 类中删除默认的电子邮件字段......

class MyUser(User):
    field = models.CharField(max_length = 10)
    a = 'hello'
    def b(self):
        print 'world'

del User.email
del MyUser.email
del Myuser.field

所有这些都给出了 AttributeError。以以下方式删除方法或属性虽然可以正常工作:

del MyUser.a
del MyUser.b

所以我很好奇为什么这不起作用;这些模型字段是什么类型的东西?

我尝试的另一件事是通过在 MyUser 中创建 email = None 来覆盖电子邮件,但这也不起作用(并且会更难看)。

提前致谢!

Ps 如果你想知道为什么;更多的是出于好奇,而不是应用程序真正需要它......但我认为最好不要在数据库中使用未使用的列。Pps 我不想更改 Django 文件以手动从用户中删除“电子邮件”。

编辑:这里的后续问题(对于那些想要做同样事情的人)在同步数据库之前,从标准 Django 模型中删除字段

4

2 回答 2

7

正如您所发现的,模型字段实际上并不是类属性,尽管它们看起来是。

模型是通过一些非常聪明但复杂的元类来构建的。当执行模型类定义时(第一次导入它的 models.py),元类会遍历该模型的所有字段定义,并调用contribute_to_class每个字段的方法。这最终将实际字段放入新类的_meta.fields属性中。所以模型类本身没有字段作为直接属性。

然后,当一个模型实例被实际实例化时,Django 使用该列表并直接设置新实例的属性,使用构造函数的参数或字段提供的默认值。因此,通过实例访问的值背后没有实际的字段代码:它是一个简单的实例属性。

无论如何,所有这一切的结果是,要从模型定义中删除一个字段,您只需将其从Model._meta.fields列表中删除即可。

于 2011-11-23T22:59:22.357 回答
0

由于Model._meta.fields是不可变列表,因此您将无法直接更改它。

但是,您可以local_fields像这样修改:

def remove_field(model_cls, field_name):
    for field in model_cls._meta.local_fields:
        if field.name == field_name:
            model_cls._meta.local_fields.remove(field)

remove_field(User, "email")
于 2020-07-02T13:16:12.273 回答