更多的Pythonic方式重复一些动作的一些属性

2024-04-26 20:17:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个Django应用程序,允许用户创建变量并命名它们

class Product(models.Model):
    name = models.CharField(max_length=40, unique=True)
    int1_name = models.CharField(max_length=60, blank=True, null=True)
    int1_default = models.IntegerField(blank=True, null=True)
    int2_name = models.CharField(max_length=60, blank=True, null=True)
    int2_default = models.IntegerField(blank=True, null=True)
    float1_name = models.CharField(max_length=60, blank=True, null=True)
    float1_default = models.FloatField(blank=True, null=True)
    float2_name = models.CharField(max_length=60, blank=True, null=True)
    float2_default = models.FloatField(blank=True, null=True)
    string1_name = models.CharField(max_length=60, blank=True, null=True)
    string1_default = models.CharField(max_length=60, blank=True, null=True)
    string2_name = models.CharField(max_length=60, blank=True, null=True)
    string2_default = models.CharField(max_length=60, blank=True, null=True)

然后它们被储存起来

class ItemData(models.Model):
    created = models.DateTimeField(default=datetime.now)
    item = models.ForeignKey(Item, editable=False)
    int1_val = models.IntegerField(blank=True, null=True)
    int2_val = models.IntegerField(blank=True, null=True)
    float1_val = models.DecimalField(blank=True, null=True, max_digits=12, decimal_places=2)
    float2_val = models.DecimalField(blank=True, null=True, max_digits=12, decimal_places=2)
    string1_val = models.CharField(max_length=60, blank=True, null=True)
    string2_val = models.CharField(max_length=60, blank=True, null=True)

当我向用户展示一个表单(他们已经创建)来填充时,我会做以下操作,用用户给变量的名称来标记字段

class ItemDataForm(ModelForm):

    # Only renames the fields based on whether the product has a name for the field
    def __init__(self,product,*args,**kwargs):
        super(ItemDataForm, self).__init__(*args, **kwargs)
        # delete all the fields that will be automatically filled in when saving
        del self.fields['created']
        # if the values is set in the product
        if product.int1_name:
            self.fields['int1_val'].label = product.int1_name
            self.fields['int1_val'].value = product.int1_default
        else:
            del self.fields['int1_val']
        if product.int2_name:
            self.fields['int2_val'].label = product.int2_name
            self.fields['int2_val'].value = product.int2_default
        else:
            del self.fields['int2_val']
        if product.float1_name:
            self.fields['float1_val'].label = product.float1_name
            self.fields['float1_val'].value = product.float1_default
        else:
            del self.fields['float1_val']
        if product.float2_name:
            self.fields['float2_val'].label = product.float2_name
            self.fields['float2_val'].value = product.float2_default
        else:
            del self.fields['float2_val']
        if product.string1_name:
            self.fields['string1_val'].label = product.string1_name
            self.fields['string1_val'].value = product.string1_default
        else:
            del self.fields['string1_val']
        if product.string2_name:
            self.fields['string2_val'].label = product.string2_name
            self.fields['string2_val'].value = product.string2_default
        else:
            del self.fields['string2_val']

有没有什么方法可以让我做得更像pythonicaly,比如有一个list Issettings.py并在上面循环:

USER_SETTABLE_VARIABLES = ['int1','int2','float1','float2','string1','string2']

这同样适用于在保存之前确保输入的数据唯一的方法:

def is_unique(self,latestSI):
    if (self.cleaned_data['int1_val'] == latestSI.int1_val and
        self.cleaned_data['int2_val'] == latestSI.int2_val and
        self.cleaned_data['float1_val'] == latestSI.float1_val and
        self.cleaned_data['float2_val'] == latestSI.float2_val and
        self.cleaned_data['string1_val'] == latestSI.string1_val and
        self.cleaned_data['string2_val'] == latestSI.string2_val):
        return False
    else:
        return True

我之所以这么问,是因为当我想添加到模型中时,我不想编辑所有这些函数。你知道吗


Tags: nameselftruedefaultfieldsmodelsvalproduct
2条回答

也许有更好的方法,但在不添加大量代码的情况下,您可以尝试以下方法:

USER_SETTABLE_VARIABLES = ['int1','int2','float1','float2','string1','string2']

for variable in USER_SETTABLE_VARIABLES:
  exec("if if product."+variable+":\n\tself.fields['" + variable + "'].label = product."+variable+"\n\tself.fields['"+variable+"'].value = product."+variable+"\nelse:\n\tdel self.fields['"+variable+"']

但这只会为您省去编写一些代码的麻烦,并使添加更多用户可设置变量变得更容易一些。但我不建议使用这种方法,因为代码的可读性会降低

使用getattr实现相同的功能:

for variable in USER_SETTABLE_VARIABLES:
   if getattr(product, variable):
       self.fields[variable].label = getattr(product, variable):
       .....
   else:
       .....        

不要用exec来做这个!getattr非常充分,安全得多,而且可读性也很强。你知道吗

class ItemDataForm(ModelForm):
    def __init__(self,product,*args,**kwargs):
        super(ItemDataForm, self).__init__(*args, **kwargs)
        del self.fields['created']
        fields = 'int1', 'int2', 'float1', 'float2', 'string1', 'string2'
        for field in fields:
            val = getattr(product, field + '_name')
            fval = field + '_val'
            if val:
                self.fields[fval].label = val
                self.fields[fval].value = getattr(product, field + '_default')
            else:
                del self.fields[fval]

相关问题 更多 >