首页 文章

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

提问于
浏览
0

我试图让模型字段的默认值(和其他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.  
            
# Должно быть уникальным''', max_length=120, unique=True, verbose_name='Именование', ) ...

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

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

所以..如果我将使用我的最后一个 answer ,这个函数将在每次调用(不仅仅是一次init的类)时使用给定的参数调用 .

1 回答

  • 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很好,第二次打电话(自我之后. call = self.foo)没有发生 . 顺便说一句,我可能要停下来 .

相关问题