Django模型 - 使用参数传递函数对象

时间:2017-03-29 18:37:49

标签: django python-3.x

我正在尝试使模型字段的默认值(和其他kwargs)更具动态性,因此我为此创建了一个函数:

def get_latest_id(cls, text, *args):
    try:
        ret = globals()[cls].objects.latest('id').id + 1 
        return text.format(ret, args)
    except:
        return text.format(1, args)

我想将此函数用作某些字段的默认值,但我需要参数来告诉函数使用什么。所以我接下来做了:

@deconstructible
class callable: 
    def __init__(self, foo, *args):
        self.foo = foo
        self.args = args

    def __call__(self):
        return self.foo(*self.args)

@deconstructible
class lazy_call: 
    def __init__(self, foo):
        self.foo = foo

    def __call__(self, *args):
        return callable(self.foo, *args) 

@lazy_call  #return this function as callable object that know its arguments
def get_latest_id(cls, text, *args):
    try:
        ret = globals()[cls].objects.latest('id').id + 1 
        return text.format(ret, args)
    except:
        return text.format(1, args)

它工作正常,但现在我注意到我有无限的迁移(如果没有错误我可以多次制作migratons并且它不会说'没有检测到变化'),它肯定与我的功能相关联。它可以修复吗?或者我的代码对django的工作原理无效?

更新示例:

class Article(models.Model):

    def __str__(self):
        return self.title

    title = models.CharField(
        default=get_latest_id('Article', 'Статья #{}'),  # <<< THIS ONE
        help_text='''Название статьи - используется для поиска в Django admin.  
            <br />  # Должно быть уникальным''',
        max_length=120, 
        unique=True, 
        verbose_name='Именование',
    ) 
    ...

我必须传递一个函数 OBJECT 来让它评估每个记录添加,但我也想使用参数因为我没有看到任何其他方式使函数通用(不仅仅是为了具体课,有一些具体的文字)。

我不能用lambda来包装我想要的东西,所以我不能在函数内部定义函数来制作一些简单的解决方案,也就是函数装饰器(django不允许两者)

所以..如果我将使用我的上一个答案,每次使用给定的参数调用此函数(不仅仅是在init的一次)。

1 个答案:

答案 0 :(得分:0)

我把这一切改写成了一个单独的类:

@deconstructible
class get_latest_id():
    def __init__(self, cls, text, *args):
        self.cls = cls
        self.text = text
        self.args = args

    def __call__(self):
        try:
            ret = globals()[self.cls].objects.latest('id').id + 1 
            return self.text.format(ret, self.args)
        except:
            return self.text.format(1, self.args)

现在迁移很好,但我不喜欢这个..语法也是如此 对于单一功能来说很重要,所以我会尝试从中做出装饰。

尝试以下:

@deconstructible
class lazy_call: 
    def __init__(self, foo):
        self.foo = foo

    def __call__(self, *args):
        self.foo.__defaults__ = args
        self.__call__ = self.foo

@lazy_call
def get_latest_id(cls, text, *args):
    try:
        latest_id = globals()[self.cls].objects.latest('id').id + 1 
        return self.text.format(latest_id, self.args)
    except:
        return self.text.format(1, self.args)

看起来很可怕,我不确定知道这里发生了什么。它没有工作(ha),没有错误,makemigratons很好,第二次电话(在自我之后。电话 = self.foo)没有发生。顺便说一句,我可能不得不停下来。