2009-05-01 7 views
85

Estoy tratando de establecer el campo a un cierto valor después de que se inicializa el formulario.Django establece el valor de campo después de inicializar un formulario

Por ejemplo, tengo la siguiente clase.

class CustomForm(forms.Form): 
    Email = forms.EmailField(min_length=1, max_length=200) 

En la vista, quiero ser capaz de hacer algo como esto:

form = CustomForm() 
form["Email"] = GetEmailString() 

return HttpResponse(t.render(c)) 

Respuesta

105

ya que no está pasando en datos POST, voy a suponer que lo que está tratando de hacer se establece un valor inicial que se mostrará en el formulario. La forma de hacerlo es con la palabra clave initial.

form = CustomForm(initial={'Email': GetEmailString()}) 

Consulte el Django Form docs para obtener más explicaciones.

Si usted está tratando de cambiar un valor después de que se envía el formulario, se puede usar algo como:

if form.is_valid(): 
    form.cleaned_data['Email'] = GetEmailString() 

Comprobar los documentos referenciados más arriba para más información sobre el uso de cleaned_data

+0

Eso es exactamente lo que quiero hacer. ¡Gracias! – Eldila

+0

Gracias, para mí también exactamente lo que necesitaba ... – Neo

+1

Esto confirma lo que sabía, pero mi 'ModelChoiceField' todavía está dando invalid_choice cuando le doy un valor' initial' :( –

-12

Otra manera de hacer esto , si ya se ha inicializado una forma (con o sin datos), y es necesario agregar más datos antes de mostrarla:

form.data['Email] = GetEmailString() 
+8

Esto falla para mí. Tengo una línea como la anterior en el método __init__ de mi formulario, y plantea "AttributeError: Esta instancia de QueryDict es inmutable" –

+0

Este código solo funciona cuando el formulario ha sido iniciado sin datos de formularios. Como resultado, un objeto inmutable como request.GET o request.POST no se vinculará, por lo que obtendrá un diccionario vacío (form.data) que se puede cambiar sin ningún error. FYI estoy usando Django 1.6.3 – potar

+0

Esto funcionará si su encabezado "Content-Type" está configurado en "multipart/form-data".No funciona cuando utiliza un tipo de contenido de "application/x-www-form-urlencoded". No sé por qué, pero fue un ***** para depurar. – teewuane

74

Si usted tiene ya initiali zed el formulario, puede usar la propiedad inicial del campo. Por ejemplo,

form = CustomForm() 
form.fields["Email"].initial = GetEmailString() 
+10

Gracias. Si bien la respuesta aceptada es la sugerida, usted gana el premio "realmente respondido la pregunta". Esto es lo que estaba buscando (y lo que aparece en google). – jason

+0

También funciona muy bien en un bucle for con un formset, simplemente use la lógica "for form in formset" y puede establecer opciones y datos iniciales como se ve arriba. – radtek

+5

¿Hay una manera diferente de hacer esto es Django 1.7/Python 3.4? Esto no funciona para mí – Jeremy

5

Algo así como Nigel Cohen funcionaría si estuviera agregando datos a una copia del conjunto de recogida de datos del formulario:

form = FormType(request.POST) 
if request.method == "POST": 
    formcopy = form(request.POST.copy()) 
    formcopy.data['Email'] = GetEmailString() 
+1

No soy un gran fan de anular los datos sin formato. Si tiene que hacer esto, probablemente debería hacer 'data [form.add_prefix ('Email')]' para tener en cuenta los casos en los que se establece un prefijo. – Josh

+2

¿Hay una manera diferente de hacer esto es Django 1.7/Python 3.4? Esto no funciona para mí – Jeremy

+0

La tercera línea puede ser un poco más corta si no es necesario mantener la forma original: 'form.data = form.data.copy()' – ZZY

6

Si desea hacerlo dentro de la forma de __init__ método por alguna razón, se puede manipular el initial dict:

class MyForm(forms.Form): 
    my_field = forms.CharField(max_length=255) 

    def __init__(self, *args, **kwargs): 
     super(MyForm, self).__init__(*args, **kwargs) 
     self.initial['my_field'] = 'Initial value' 
0

acaba de cambiar su campo Form.data:

class ChooseProjectForm(forms.Form): 
    project = forms.ModelChoiceField(queryset=project_qs) 
    my_projects = forms.BooleanField() 

    def __init__(self, *args, **kwargs): 
     super(ChooseProjectForm, self).__init__(*args, **kwargs) 
     self.data = self.data.copy() # IMPORTANT, self.data is immutable 
     # any condition: 
     if self.data.get('my_projects'): 
      my_projects = self.fields['project'].queryset.filter(my=True) 
      self.fields['project'].queryset = my_projects 
      self.fields['project'].initial = my_projects.first().pk 
      self.fields['project'].empty_label = None # disable "-----" 
      self.data.update(project=my_projects.first().pk) # Update Form data 
      self.fields['project'].widget = forms.HiddenInput() # Hide if you want 
Cuestiones relacionadas