在Django中将动态配置与ModelField表单验证一起使用

时间:2018-07-18 16:31:32

标签: django postgresql validation django-models django-admin

我已经建立了一个名为Configuration的模型,该模型包含可配置的详细信息,例如maximum_stake,并在admin.py中进行了注册,以便管理员可以随时更改它们。

我的大部分验证都是通过自然的ModelForm验证完成的,但是当我尝试通过Configuration模型中动态变化的约束来执行此操作时,Postgre抱怨该关系不存在(因此我无法创建要构建的迁移或编辑配置模型表)。但是,即使进行了这些更改,数据库也不满意。还有另一种方法吗?

# models.py

class Investor(models.Model):
    stake = models.DecimalField(max_digits=4, decimal_places=2, default=0.00)

class InvestorForm(forms.ModelForm):
    stake = forms.DecimalField(help_text="The income stake as a percentage (0.00% - 8.00%)", validators=[
        MinValueValidator(0, f'Stake must be between 0.00%% and {getConfig(ConfigData.MAXIMUM_STAKE)}.00%%'),
        MaxValueValidator(getConfig(ConfigData.MAXIMUM_STAKE),
                          f'Stake must be between 0.00%% and {getConfig(ConfigData.MAXIMUM_STAKE)}.00%%')
    ])

    class Meta:
        model = Investor
        fields = '__all__'

1 个答案:

答案 0 :(得分:1)

使用动态约束时,可以使用ModelForm的Clean方法检查验证:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
  <p1> Please enter your maximum spending price </p1>
  <input id="maxprice" />
  <button onclick="filter()"> Filter </button>
  <br />
  <p1> Select a genre </p1>
  <select id="festivalgenre">
    <option value="Rock"> Rock </option>
    <option value="Pop"> Pop </option>
    <option value="Alternative"> Alternative </option>
    <option value="Dance"> Dance </option>
  </select>
</body>
</html>

或者您可以按照以下步骤创建自定义Django字段:

 def clean(self):
        cleaned_data = super().clean()
        current_stake = cleaned_data.get("stake")
        minimum_stake = 0
        maximum_stake = ConfigData.objects.first().maximum_stake #get the object from database where the configuration is saved dynamically here

        if not(current_stake > minimum_stake and current_stake <= maximum_stake):
            # Only do something if both fields are valid so far or raise error
            raise forms.ValidationError(f'Stake must be between {minimum_stake}%% and {maximum_stake}.00%%')

然后只需在模型表单中将其用作:

from django import forms class CustomStakeField(forms.Field): def to_python(self, value): return float(value) def validate(self, value): """Check if value lies within range""" super().validate(value) minimum_stake = 0 maximum_stake = ConfigData.objects.first().maximum_stake #get the object from database where the configuration is saved dynamically here if not(current_stake > minimum_stake and current_stake <= maximum_stake): # Only do something if both fields are valid so far or raise error raise forms.ValidationError(f'Stake must be between {minimum_stake}%% and {maximum_stake}.00%%')