Avi*_*Avi 5 python architecture django python-3.x
如何在常量中定义 Django 模型字段并随处使用。例如,如果我有一个模型,如:-
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField()
Run Code Online (Sandbox Code Playgroud)
我想要做的是为 Author 模型中的字段定义常量,并在模型中提供常量而不是字段名称,例如:-
KEY_FIRST_NAME = 'first_name'
KEY_LAST_NAME = 'last_name'
KEY_EMAIL = 'email'
Run Code Online (Sandbox Code Playgroud)
并且作者模型应该使用常量而不是确切的键,例如:-
class Author(models.Model):
KEY_FIRST_NAME = models.CharField(max_length=30)
KEY_LAST_NAME = models.CharField(max_length=40)
KEY_EMAIL = models.EmailField()
Run Code Online (Sandbox Code Playgroud)
如何做这样的事情,直接分配给常量在这里不起作用。
我想将所有字段名称存储在常量中,并且在需要的任何地方我都想使用常量而不是字符串字段名称。
这样做的目的是如果在以后的版本中文件名称有任何更改,那么我只想在一个地方更改,并且应该反映所有地方。
如果这是不可能的,或者它会使代码过于复杂,正如@dirkgroten 的一种方法所建议的那样,那么最好的做法是将模型字段定义为常量并在其他地方使用它们(除了内部模型,就像我们所指的那样)管理门户或任何其他地方的那些字段)。
简短的回答:你不能在 Python 中做到这一点,期间(实际上我不认为你可以在任何语言中做到这一点,但有人肯定会证明我错了 xD)。
现在,如果我们回到您真正的“问题” - 如果模型的字段名称发生更改,则不必更改客户端代码 - 您首先需要判断您的意思是“python 属性名称”还是“底层数据库字段”姓名”。
对于第二种情况,数据库字段名称不必与 Python 属性名称匹配,Django 模型字段采用db_column参数来处理这种情况。
对于第一种情况,我不得不说这是一个非常通用的(并且无论如何都不是新的)API 设计问题,通常的答案是“一旦公共 API 中包含了名称,您就不应该更改它”。已被释放”。现在事情发生了,有时你必须这样做。这里最好的解决方案是使用计算属性,在弃用期间将旧名称重定向到新名称,并在所有客户端代码移植后将其删除。
以您的模型为例,将 'first_name' 更改为 'firstname':
class Author(models.Model):
# assuming the database column name didn't change
# so we can also show how to us `db_column` ;)
firstname = models.CharField(
max_length=30,
db_column='first_name'
)
@property
def first_name(self):
# shoud issue a deprecation warning here
return self.firstname
@first_name.setter
def first_name(self, value):
# shoud issue a deprecation warning here
self.firstname = value
Run Code Online (Sandbox Code Playgroud)
如果您有十几个字段需要重命名,您肯定会想要编写一个自定义描述符(=> 计算属性),而不是保持干燥:
class Renamed(object):
def __init__(self, new_name):
self.new_name = new_name
def __get__(self, instance, cls):
if instance is None:
return self
# should issue a deprecation warning here
return getattr(instance, self.new_name)
def __set__(self, instance, value):
# should issue a deprecation warning here
setattr(instance, self.new_name, value)
class Author(models.Model):
firstname = models.CharField(
max_length=30,
db_column='first_name'
)
first_name = Renamed("firstname")
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2410 次 |
| 最近记录: |