我需要使用名称定义Django模型字段,该字段in
是Python语言关键字.这是语法错误:
class MyModel(models.Model): in = jsonfield.JSONField()
我怎样才能做到这一点?
我需要这个名字的原因是当我使用django-rest-framework的ModelSerializer
类时,字段名被用作序列化输出的键,我认为操作django的Model
类而不是ModelSerializer
类来获取我想要的输出可能更容易.
一般来说,你没有.避免在标识符中使用关键字.一般的Python约定是为这些名称添加下划线; 这是in_
:
class MyModel(models.Model): in_ = jsonfield.JSONField()
但是,Django禁止以下划线结尾的名称,因为下划线与它们的过滤器命名约定冲突,所以你必须提出一个不同的名称; 选一个仍然描述你的情况; 我选择包含而不是in,作为对你想要做什么的猜测:
class MyModel(models.Model): contained_in = jsonfield.JSONField()
如果要尝试匹配现有数据库模式,请使用以下db_column
属性:
class MyModel(models.Model): contained_in = jsonfield.JSONField(db_column='in')
如果你想要顽固,在普通的类中你可以setattr()
在创建类之后使用字符串而不是标识符:
class Foo: pass setattr(Foo, 'in', 'some value')
但你必须使用setattr()
,getattr()
,delattr()
和/或vars()
无处不在代码中能够访问此.
在Django中,你会有一个额外的复杂功能,即一个models.Model
子类使用元类将你的类成员解析成其他结构,并且添加一个额外的字段在setattr()
没有(很多)额外工作的情况下无法工作来重新执行元类的操作确实.您可以使用该field.contribute_to()
方法,在Django准备好类之后调用它(从这篇博客文章中获取的技术):
from django.db.models.signals import class_prepared def add_field(sender, **kwargs): if sender.__name__ == "MyModel": field = jsonfield.JSONField('in') field.contribute_to_class(sender, 'in') class_prepared.connect(add_field)
但是在创建模型类之前,必须确保已注册此挂钩.