Django - 将额外的参数传递给默认的可调用函数

时间:2016-05-24 16:41:03

标签: django python-2.7 import python-import

原标题:无法导入正常工作

我正在尝试生成一个函数,该函数将创建一个随机的字母数字,并将其作为django中模型字段的默认值。

因此,对于单一模型,我确实喜欢这样:

# utils.py
def generate_random_unique_code_for_model():
    from .models import mymodel 
    while 1:
        code = random_code()  #my custom function to generate random alphanumeric
        try:
            mymodel.objects.get(myfield=code)
        except mymodel.DoesNotExist:
            return code

 #models.py
 class mymodel(models.Model):
     #other fields
     myfield = models.CharField(default=generate_random_unique_code_for_model)

这段代码工作正常,但现在我必须为另一个模型提供类似的功能,所以为了遵循DRY原则,我试图使模型,fieldnames动态。所以基本上我想在from some_app.models import some_model函数中完成generate_random_unique_code_for_model

def get_model(location, model_name):
    try:
        module = __import__('.'.join(location), globals(), locals(), [model_name], -1)
        model_instance = getattr(module, model_name)
    except:
        raise ImportError(_('Could not import %(model_name)s from %(location)s') % {'model_name': model_name,
                                                                                    'location': '.'.join(location)})
    return model_instance


def generate_random_unique_code_for_model(location, model_name, field_name):
    model_object = get_model(location, model_name)
    kwargs = {field_name: ''}
    while 1:
        code = random_code()
        kwargs[field_name] = code
        try:
            model_object.objects.get(**kwargs)
        except model_object.DoesNotExist:
            return code
#models.py
class mymodel_name(models.Model):
    #other fields
    myfield_name = models.CharField(default=generate_random_unique_code_for_model(['myapp_name', 'mymodel_name'], 'myfield_name'))      

在调试时,当我在调试时dir(module)时,我在列表中看不到mymodel_name。有任何变通方法吗?

1 个答案:

答案 0 :(得分:1)

问题是默认采用可调用函数,因此每当实例化模型实例时,都会调用默认函数。但是,自从我在第二种情况下调用该函数时,无论何时启动服务器并加载模型,它都会在创建模型类之前尝试加载模型。所以问题归结为将带有参数的可调用函数传递给默认值,这是目前无法实现的。所以我做的是:

def make_random():
    return generate_random_unique_code_for_model(['myapp_name', 'mymodel_name'], 'myfield_name')


class mymodel_name(models.Model):
    #other fields
    myfield_name = models.CharField(default=make_random)