2014-05-18 17 views
3

В моем приложении у меня есть CreateView, который должен инициализировать некоторые поля модели со значением по умолчанию, отличным от значения по умолчанию, определенного внутри модели.Django - присвоить значение по умолчанию для поля в ModelForm

Я не хочу, чтобы пользователь, чтобы изменить значение, таким образом, я поставил на поле в списке exclude

class AForm(ModelForm): 
    class Meta: 
     model = AModel 
     exclude = ['a_field'] 

class AView(CreateView): 
    form_class = AForm 

Вопрос: где я установить значение a_field?

Я попытался определить clean методы внутри AForm, как таким образом

class AForm(ModelForm): 
    [...] 
    def clean(self): 
     d = super(AForm, self).clean() 
     d['a_field'] = 10 
     return d 

однако a_field устанавливается на то, что его значение по умолчанию определяется в модели, а не 10. Я также попытался определить clean_a_field, но это просто не выполнено.

Если удалить a_field из exclude списка, то clean и clean_a_field будет работать, но форма не будет проверять, если я не сделать некоторые <input name="a_field"> внутри шаблона, который не является оптимальным.

+0

Вы определяете 'clean_a_field' или просто' clean'? – SunnySydeUp

+0

Я пробовал оба. Они оба игнорируются. –

+0

Действительно? Необходимо всегда вызывать чистый метод формы. Альтернативой является переопределение метода сохранения формы. – SunnySydeUp

ответ

1

мне удалось решить эту проблему таким образом, что делает меня устраивает, хотя я до сих пор не 100% довольны кодом.

a_field является обязательным (по модели) полем, поэтому в шаблоне необходимо отобразить <input name="a_field">. Хитрость в том, чтобы сделать a_field без необходимости:

class AForm(ModelForm): 
    a_field = Field(required=False, 
        widget=forms.HiddenInput) 
    class Meta: 
     model = AModel 

    def clean_a_field(self): 
     return 10 

Таким образом, я могу избежать визуализации поля в шаблоне, и форма будет еще проверить. И даже если форма отображается с {{ form.as_p }}, widget=forms.HiddenInput экономит мой день.

0

Вы устанавливаете значение по умолчанию в модели. Из официального document,
a_field = models.CharField (max_length = 7, по умолчанию = ''), например

+0

Это не мешает пользователю изменять значение. –

+0

Вы используете modelForm для этого? Если тогда вам нужно добавить атрибут disabled = "disabled" в поле ввода. Google дал следующее: http://stackoverflow.com/questions/19489699/how-to-add-class-id-placeholder-attributes-to-a-field-in-django-model-forms – user2707389

+0

Да, я использую ' ModelForm'. Отключение поля в HTML не препятствует пользователю редактировать его, если она действительно хочет (или если у нее старый браузер, не признающий атрибут «disabled»). Кроме того, поле по-прежнему будет отображаться в форме, но это не то, что я хочу: я хочу выбрать значение для пользователя. Использование 'HiddenIntput' не помогает: пользователь может редактировать, если захочет. Совмещение с 'clean' или' clean_a_field' будет работать, но против DRY, и я не могу поверить, что нет более простого способа. –

0

У меня есть способ справиться с этой ситуацией. Выполните следующую процедуру:

  1. Удалить 'a_field' из исключает в альфа-форму.

  2. Не подвергайте 'a_field' в HTML-шаблоне. т. е. не предоставлять пользователю возможность изменять значение через форму в шаблоне. Это гарантирует, что обычный пользователь не изменит значение.

  3. Для полного предотвращения, over-rideget_form_kwargs на вид. Это обеспечит или более-ездить на желаемое значение «a_field» и спасти

например

class AView(CreateView): 
    form_class = AForm 

    def get_form_kwargs(self): 
     kwargs = super(AView, self).get_form_kwargs() 
     if self.request.method in {'POST', 'PUT'}: 
      # Change post data to over-ride or provide value of 'a_field' 
      data = self.request.POST.copy() 
      data.update({ 
       'a_field': 'value' 
      }) 
      kwargs['data'] = data 
     return kwargs 
4

Исключить поле из формы, то в окне вы можете задать значение, прежде чем сохранить форму:

form = AForm(request.POST) 
if form.is_valid(): 
    new_record = form.save(commit=False) 
    new_record.a_field = 10 
    new_record.save() 

Вы также можете захотеть, чтобы избежать exclude списка и указать, какие поля вы хотите включить в определение формы fields. См. Первый абзац here in the docs.

+0

Это хорошая идея, но, на мой взгляд, она не сочетается с CreateView. Форма сохраняется 'CreateView.form_valid()'; переписывание этого метода без вызова 'super' для меня не очень перспективно. –

Смежные вопросы