Django选择字段验证

niknxzdl  于 2023-02-20  发布在  Go
关注(0)|答案(1)|浏览(147)

我有一个模型,它有一个选择字段,其中包含在运行时加载的选择。

from some_utils import get_currency_options

class Product(models.Model):
    name = models.CharField(max_length=20)
    currency = models.CharField(max_length=3, null=True, blank=True, default="USD", choices=[])

    def clean(self):
    # getting the currency options at execution time, options may vary at different times
    currency_code_options = get_currency_options()

    if self.currency and self.currency not in currency_code_options:
        raise ValidationError({"currency": f"Invalid currency code {self.fb_check_currency}."})

    super(Product, self).clean()

请忽略这里糟糕的设计,它是这样定义的,因为我们需要与遗留系统集成。
在Django管理中,我有这样一个表单

from some_utils import get_currency_options

class ProductAdminForm(ModelForm):
    currency_choices = get_currency_options()

    @staticmethod
    def _values_list_to_options(values_list):
        return [(val, val) for val in values_list]

    def __init__(self, *args, **kwargs):
        super(ProductAdminForm, self).__init__(*args, **kwargs)
        self.fields["currency"] = ChoiceField(choices=self._values_list_to_options(self.currency_choices))

class ProductAdmin(admin.ModelAdmin):
    form = ProductAdminForm

现在的问题是,当我进入Django管理并想要更新货币选项时,它无法保存,并显示一个错误,说货币不是一个有效的选项。我理解这是由于选择列表是空的,我试图覆盖cleanclean_all方法,但它没有工作。
管理员更新操作会触发哪个方法?是否有办法使用get_currency_options方法将货币选项加载到验证器中,这样如果我的选择与其中一个值匹配,它就可以通过验证器?

4ioopgfo

4ioopgfo1#

我有同样的错误。在你的情况下,你需要概述你的模型类中的clean_field方法。例如:

from some_utils import get_currency_options

class Product(models.Model):
    name = models.CharField(max_length=20)
    currency = models.CharField(max_length=3, null=True, blank=True, default="USD", choices=[])

    def clean_fields(self, exclude=None):
        exclude = ['currency']
        super().clean_fiedls(exclude=exclude)

    def clean(self):
        self.validate_currency()
        super().clean()

    def validate_currency(self):
        # getting the currency options at execution time, options may vary at different times
        currency_code_options = get_currency_options()

        if self.currency and self.currency not in currency_code_options:
            raise ValidationError({"currency": f"Invalid currency code {self.fb_check_currency}."})

相关问题