У меня есть таблица, которая содержит различные типы настроек.Я хочу отображать и проверять каждый параметр по-разному в форме.Например, если задано целое число или строка.
Это моя модель
class Setting(models.Model):
SETTING_TYPES = (
(u'1', u'Decimal'),
(u'2', u'Integer'),
(u'3', u'String'),
)
type = models..CharField(max_length=2, choices=SETTING_TYPES)
name = models.CharField(max_length=50, unique=True)
value = models.CharField(max_length=200)
Поэтому, если тип равен 1, я хочу ограничить запись в форме и проверить фактчто я ожидаю десятичную.Но если тип равен 3, мне нужно показать более крупную форму ввода и сравнить ее с фактом, что я ожидаю строку.
Несколько мест, которые я могу увидеть с возможностью сделать это:
- В пользовательском виджете
- Переопределив класс BaseModelFormSet, чтобы изменить свойства поля при инициализации (http://snippets.dzone.com/posts/show/7936)
- , используя пользовательский шаблонный фильтр, который оценит тип и затем отобразитформа вручную через пользовательский шаблон для этого типа настройки
- сохраняет тип и значение вместе в jsonfield и использует что-то вроде http://www.huyng.com/archives/django-custom-form-widget-for-dictionary-and-tuple-key-value-pairs/661/, чтобы изменить отображение и проверку значения настройки в одном месте..
С опцией 1 я не уверен, использую ли я пользовательский виджет в поле «значение», если он сможет получить доступ к полю «тип», чтобы определить, как представлять «value '
Я попробовал вариант 2, и хотя я мог получить доступ к элементам формы, я не смог получить доступ к значениям формы, чтобы определить тип параметра (возможно, они еще не были связаны?).Я думаю, что этот маршрут может быть самым простым, но мне понадобится доступ к значениям формы.
class BaseSettingFormset(BaseModelFormSet):
def __init__(self, *args, **kwargs):
super(BaseSettingFormset, self).__init__(*args, **kwargs)
for form in self.forms:
# here i would access the type value and then change the widget propeties below
if form.fields['type'] == 3: # DOESN"T WORK :(
# change the widget and field properties
form.fields['value'].help_text='some text'
form.fields['value'].widget = CustomWidget() # or switch from decimal to string widgets..
def editProfile(request, strategy_id):
settingModelFormset = modelformset_factory(profile, formset=BaseSettingFormset)
... retrieve the values and show them..
(во время публикации я нашел сообщение, которое может позволить мне связать форму во время инициализации и поэтому иметьдоступ к значению см. django - как я могу получить доступ к полю формы из пользовательского виджета )
Вариант 3 работает для отображения поля, но не для проверки каких-либо данных.Я думаю, что мне нужно было бы объединить его с опцией 2 для проверки во время сохранения.
#Custom template filter
@register.filter(name='show_setting')
def show_setting(form):
setting = field_value(form['type']) # calls another function to retrieve value (works ok)
# render page using custom template that can alter the form to show a small field or text area etc.
# can also add js validations here.. (but no server validations)
if setting:
return render_to_string('setting-'+str(setting)+'.html', { 'form': form })
.
Какой метод будет лучше (или есть другой способ), и как мнезавершить это?Или я поступаю неправильно, есть ли более djangoesc способ решить мою проблему?