Валидация поля выбора Django в админке

У меня есть модель, которая имеет поле выбора с вариантами, загруженными во время выполнения.

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 admin и хочу обновить опцию валюты, она не сохраняется с ошибкой, говорящей, что валюта не является действительной опцией. Я понимаю, что это происходит из-за того, что список выбора пуст, я пытался переопределить метод clean и clean_all, но это не сработало.

Какой метод вызывает операцию обновления в админке? Есть ли способ использовать метод get_currency_options для загрузки опций валюты в валидатор, чтобы если мой выбор совпадает с одним из значений, он прошел валидатор?

У меня такая же ошибка. В вашем случае необходимо сделать обзор метода 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}."})
Вернуться на верх