首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Django模型中存储函数调用

在Django模型中存储函数调用
EN

Stack Overflow用户
提问于 2018-07-13 12:48:07
回答 3查看 643关注 0票数 0

目前,我将一系列对象存储为字典字典,并在其中存储对字典外定义的函数的调用。这些函数是特定于对象的,不能泛化。在字典中,我可以直接引用函数例如:'some_property': function_name,当我稍后在dictionary['some_property'](arg_1, arg_2)上调用这个函数时,这个函数就会被调用。我希望将这个字典迁移到django模型,但是我无法从模型中复制这个功能。

我现在拥有的是:

代码语言:javascript
复制
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
        },
}

然后,当与用户定义的时间框架组合在一起时,将调用:

代码语言:javascript
复制
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模型来复制这些数据,如下所示:

代码语言:javascript
复制
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

像这样的东西存在吗?我该怎么做呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-07-13 13:01:21

实际上,您不能将函数(我指的是Python函数)存储在SQL数据库中。但是您可以存储任何文本值,并且您可以在模型中有一个'key:func‘的块,即:

代码语言:javascript
复制
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]
票数 1
EN

Stack Overflow用户

发布于 2018-07-13 12:59:21

您可以做的一件事是使用CharField,然后使用eval。然而,使用eval通常是一个巨大的安全风险。任何进入它的python代码都将被执行,并且您不希望web应用程序中有类似的东西。

另一种选择是有一个查找系统。比方说,您可以拥有一个CharField,它的选择与这样的字典相对应:

代码语言:javascript
复制
models.py
...
slug_treatment = models.CharField(max_length=100, choices=function_choices)
...

然后:

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2018-07-13 14:08:09

Sry让我有点困惑,但根据我的理解,也许您可以声明类中的所有函数,并使用slug_treament作为参数,在需要时调用哪个函数。

让我们画一点

代码语言:javascript
复制
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方法”,类似于数据库中的列,但它不是持久化的,而是在数据库中进行强制转换)。

代码语言:javascript
复制
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中对其进行计算,我想这是可能的,但是非常不安全,我不建议使用

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51325476

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档