Валидация поля выбора 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}."})