目前,我将一系列对象存储为字典字典,并在其中存储对字典外定义的函数的调用。这些函数是特定于对象的,不能泛化。在字典中,我可以直接引用函数例如:'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像这样的东西存在吗?我该怎么做呢?
发布于 2018-07-13 13:01:21
实际上,您不能将函数(我指的是Python函数)存储在SQL数据库中。但是您可以存储任何文本值,并且您可以在模型中有一个'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]发布于 2018-07-13 12:59:21
您可以做的一件事是使用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)发布于 2018-07-13 14:08:09
Sry让我有点困惑,但根据我的理解,也许您可以声明类中的所有函数,并使用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)或者,您可以使用它作为prorperty方法,而不是持久化数据(因此,每次调用queryset时都会对段塞进行评估,因此它是dinamic方法,而不是持久化的“Obs.:Property方法”,类似于数据库中的列,但它不是持久化的,而是在数据库中进行强制转换)。
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中对其进行计算,我想这是可能的,但是非常不安全,我不建议使用。
https://stackoverflow.com/questions/51325476
复制相似问题