Django Dynamic Widget / Представление поля формы - PullRequest
2 голосов
/ 09 января 2011

У меня есть таблица, которая содержит различные типы настроек.Я хочу отображать и проверять каждый параметр по-разному в форме.Например, если задано целое число или строка.

Это моя модель

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, мне нужно показать более крупную форму ввода и сравнить ее с фактом, что я ожидаю строку.

Несколько мест, которые я могу увидеть с возможностью сделать это:

  1. В пользовательском виджете
  2. Переопределив класс BaseModelFormSet, чтобы изменить свойства поля при инициализации (http://snippets.dzone.com/posts/show/7936)
  3. , используя пользовательский шаблонный фильтр, который оценит тип и затем отобразитформа вручную через пользовательский шаблон для этого типа настройки
  4. сохраняет тип и значение вместе в 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 способ решить мою проблему?

1 Ответ

0 голосов
/ 09 января 2011

Я считаю, что вы ищете пользовательский валидатор , переданный в конструктор CharField.

Другим, возможно, более элегантным решением в зависимости от ситуации будет создание собственного класса поля, который расширяет CharField и перегружает его код проверки.

...