当前,我将一系列对象存储为字典的字典,并且在其中存储对在字典外部定义的函数的调用。这些功能是特定于对象的,不能一概而论。在字典中,我可以直接引用该函数,例如:'some_property': function_name
,稍后在dictionary['some_property'](arg_1, arg_2)
上调用该函数时,该函数将被调用。我正在将字典词典迁移到Django模型,但是我看不到如何从模型中复制此功能。
我目前拥有的东西:
dictionaries.py
def year_camel_month(filename, **kwargs):
month = kwargs['month'].title()
return filename.format(str(kwargs['year']), month)
def year_month(filename, **kwargs):
month = kwargs['month']
return filename.format(str(kwargs['year']), month.lower())
data_source_families = {
'dataset_1': {
'source_url': 'https://example.org/url/subfolder',
'slug': 'slug_that_changes_predictably_over_time{}-{}',
'slug_treatment': year_camel_month
},
'dataset_2': {
'source_url': 'https://example2.org/url/subfolder',
'slug': 'slug_that_changes_predictably_over_time{}-{}',
'slug_treatment': year_month
},
}
随后在与用户定义的时间范围结合使用时会被调用:
get_data.py
from .dictionaries import data_source_families
slug = data_source_families[selected_dataset]['slug']
processed_slug = data_source_families[selected_dataset]['slug_treatment'](slug, some_kwargs)
url = data_source_families[selected_dataset]['source_url'] + processed_slug
这很好。我正在寻求通过创建可复制此内容的Django模型来开发功能来提高一致性(并使这些数据可用于其他程序),例如:
models.py
def year_camel_month(filename, **kwargs):
month = kwargs['month'].title()
return filename.format(str(kwargs['year']), month)
def year_month(filename, **kwargs):
month = kwargs['month']
return filename.format(str(kwargs['year']), month.lower())
class DataSourceFamilies(models.Model):
name = models.CharField(max_length=200, unique=True)
source_url = models.CharField(max_length=300, blank=False)
slug = models.CharField(max_length=200, blank=False)
--> slug_treatment = models._____(choices=list_of_functions) <--
def __str___(self):
return self.name.name
是否存在类似的东西?我将如何去做?
答案 0 :(得分:1)
您可以做的一件事是使用CharField,然后eval
。但是,使用eval
通常会带来巨大的安全风险。输入它的所有python代码都将被执行,并且您不希望在Web应用程序中有任何类似的代码。
另一个选择是拥有一个查找系统。您可以说,有一个CharField,其选择对应于这样的字典:
models.py
...
slug_treatment = models.CharField(max_length=100, choices=function_choices)
...
然后:
get_data.py
function_lookup = {
"year_month": year_month,
"year_camel_month": year_camel_month
}
processed_slug = function_lookup[data_source.slug_treatment](slug, some_kwargs)
答案 1 :(得分:1)
实际上,您不能在SQL数据库中存储函数(我指的是Python函数)。但是您可以存储任何文本值,并且模型中可以有一个“ key:func”的字典,即:
class DataSourceFamilies(models.Model):
name = models.CharField(max_length=200, unique=True)
source_url = models.CharField(max_length=300, blank=False)
slug = models.CharField(max_length=200, blank=False)
SLUG_TREATEMENTS = [
# key, label, function
('year_camel_month', "Year, Camel month", year_camel_month),
('year_month': "Year month", year_month),
]
SLUG_TREATEMENTS_ACTIONS = {
k: func
for k, label, func in SLUG_TREATEMENTS
}
SLUG_TREATEMENTS_CHOICES = [
(k, label)
for k, label, func in SLUG_TREATEMENTS
]
slug_treatment = models.CharField(
max_length=50 # let's have a little headroom,
choices=SLUG_TREATMENT_CHOICES
)
def get_slug_treatment_func(self):
return self.SLUG_TREATEMENTS_ACTIONS[self.slug_treatment]
答案 2 :(得分:0)
对我来说有点困惑,但是根据我的理解,也许您可以在类中声明所有函数,并使用slug_treament作为参数,在需要时可以调用该函数。
让我们画一点
YEAR_CAMEL_MONTH=1
YEAR_MONTH=2
SLUG_TREATEMENTS_CHOICES = [
(YEAR_CAMEL_MONTH: 'year_camel_month'),
(YEAR_MONTH: 'year_month'),
]
class DataSourceFamilies(models.Model):
...
slug = models.CharField(max_length=200, blank=False)
slug_treatment = models.IntegerField(choices=SLUG_TREATMENT_CHOICES)
def year_camel_month(self):
... # Your logic
return formated_slug
def year_month(self):
... # Your logic
return formated_slug
def save(self *args **kwargs):
if self.slug_treatment == YEAR_CAMEL_MONTH:
self.slug = self.year_camel_month()
elif self.slug_treatment == YEAR_MONTH:
self.slug = self.year_month()
super(DataSourceFamilies, self).save(*args, **kwargs)
或者您可以将其用作属性方法,而不是持久数据(因此,每次调用查询集时都会评估该段,因此它是动态的,而不是持久的”。 Obs 。:属性方法的工作方式类似于数据库中的列,但不能持久保存,就像数据库中的CAST
class DataSourceFamilies(models.Model):
...
slug_treatment = models.IntegerField(choices=SLUG_TREATMENT_CHOICES)
@property
def slug(self):
if self.slug_treatment == YEAR_CAMEL_MONTH:
return slug = self.year_camel_month()
elif self.slug_treatment == YEAR_MONTH:
return slug = self.year_month()
https://docs.djangoproject.com/en/2.0/topics/db/models/
不好。:如果您尝试从文本中获取代码并在python中对其进行评估,我想它是可能的,但是是非常不安全的,因此我不建议这样做 < / p>