Skip to main content
 首页 » 编程设计

django之为多个属性重复某些操作的更 Pythonic 方式

2025年05月04日27落叶无声

我有一个 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) 

然后存储起来<​​/p>

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 那样做一个列表是 settings.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 

我之所以问是因为当我想添加到模型时我不想编辑所有这些功能。

请您参考如下方法:

不要为此使用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]