plantillas method formularios form avanzados django django-templates

method - ¿Mostrar el valor de un campo de formulario django en una plantilla?



post django (11)

En Django 1.2, {{form.data.field}} y {{form.field.data}} están todos bien, pero no {{form.field.value}}.
Como han dicho otros, {{form.field.value}} solo es Django 1.3+, pero no hay ninguna especificación en https://docs.djangoproject.com/en/1.3/topics/forms/ . Se puede encontrar en https://docs.djangoproject.com/en/1.4/topics/forms/ .

Tengo un formulario con una propiedad de correo electrónico. Cuando se usa {{form.email}} en caso de algún error de validación, django aún presenta el valor anterior en el atributo de valor de la etiqueta de entrada:

<input type="text" id="id_email" maxlength="75" class="required" value="[email protected]" name="email">

Quiero renderizar la etiqueta de entrada (para agregar un código javascript y una clase de error en caso de un error). Por ejemplo, esta es mi plantilla en lugar de {{form.email}}:

<input type="text" autocomplete="on" id="id_email" name="email" class="email {% if form.email.errors %}error{% endif %}">

Sin embargo, esto no muestra el valor erróneo ("[email protected]" en este ejemplo) para el usuario. ¿Cómo obtengo el valor del campo en la plantilla?


Esta fue una solicitud de función que se solucionó en Django 1.3.

Aquí está el error: https://code.djangoproject.com/ticket/10427

Básicamente, si estás ejecutando algo después de la versión 1.3, en las plantillas de Django puedes hacer:

{{ form.field.value|default_if_none:"" }}

O en Jinja2:

{{ form.field.value()|default("") }}

Tenga en cuenta que field.value() es un método, pero en Django templates () se omiten, mientras que en el método Jinja2 las llamadas son explícitas.

Si quieres saber qué versión de Django estás ejecutando, te dirá cuándo ejecutas el comando runserver.

Si tiene algo antes de la versión 1.3, probablemente pueda usar la solución publicada en el error anterior: https://code.djangoproject.com/ticket/10427#comment:24


Esto parece funcionar.

{{ form.fields.email.initial }}


La solución propuesta por Jens es correcta. Sin embargo, resulta que si inicializa su ModelForm con una instancia (ejemplo a continuación) django no llenará los datos:

def your_view(request): if request.method == ''POST'': form = UserDetailsForm(request.POST) if form.is_valid(): # some code here else: form = UserDetailsForm(instance=request.user)

Entonces, hice mi propia clase base ModelForm que llena los datos iniciales:

from django import forms class BaseModelForm(forms.ModelForm): """ Subclass of `forms.ModelForm` that makes sure the initial values are present in the form data, so you don''t have to send all old values for the form to actually validate. """ def merge_from_initial(self): filt = lambda v: v not in self.data.keys() for field in filter(filt, getattr(self.Meta, ''fields'', ())): self.data[field] = self.initial.get(field, None)

Entonces, el ejemplo de vista simple se ve así:

def your_view(request): if request.method == ''POST'': form = UserDetailsForm(request.POST) if form.is_valid(): # some code here else: form = UserDetailsForm(instance=request.user) form.merge_from_initial()


Probé algunas de las posibilidades mencionadas, y así es como resolví mi problema:

#forms.py class EditProfileForm(forms.ModelForm): first_name = forms.CharField(label=''First Name'', widget=forms.TextInput( attrs={''class'': ''form-control''}), required=False) last_name = forms.CharField(label=''Last Name'', widget=forms.TextInput( attrs={''class'': ''form-control''}), required=False) # username = forms.CharField(widget=forms.TextInput( # attrs={''class'': ''form-control''}), # required=True) address = forms.CharField(max_length=255, widget=forms.TextInput( attrs={''class'': ''form-control''}), required=False) phoneNumber = forms.CharField(max_length=11, widget=forms.TextInput( attrs={''class'': ''form-control''}), required=False) photo = forms.ImageField(label=''Change Profile Image'', required=False) class Meta: model = User fields = [''photo'', ''first_name'', ''last_name'', ''phoneNumber'', ''address''] # ''username'', #views.py def edit_user_profile(request, username): user = request.user username = User.objects.get(username=username) user_extended_photo = UserExtended.objects.get(user=user.id) form = EditProfileForm(request.POST or None, request.FILES, instance=user) user_extended = UserExtended.objects.get(user=user) if request.method == ''POST'': if form.is_valid(): # photo = UserExtended(photo=request.FILES[''photo''] or None, ) user.first_name = request.POST[''first_name''] user.last_name = request.POST[''last_name''] user_extended.address = request.POST[''address''] user_extended.phoneNumber = request.POST[''phoneNumber''] user_extended.photo = form.cleaned_data["photo"] # username = request.POST[''username''] user_extended.save() user.save() context = { ''form'': form, ''username'': username, ''user_extended_photo'': user_extended_photo, } return render(request, ''accounts/profile_updated.html'', context) else: photo = user_extended.photo first_name = user.first_name last_name = user.last_name address = user_extended.address phoneNumber = user_extended.phoneNumber form = EditProfileForm( initial={''first_name'': first_name, ''last_name'': last_name, ''address'': address, ''phoneNumber'': phoneNumber, ''photo'': photo}) context = { ''form'': form, ''username'': username, ''user_extended_photo'': user_extended_photo, } return render_to_response(''accounts/edit_profile.html'', context, context_instance=RequestContext(request)) #edit_profile.html <form action="/accounts/{{ user.username }}/edit_profile/" method="post" enctype=''multipart/form-data''> {% csrf_token %} <div class="col-md-6"> <div class="form-group"> {{ form.as_p }} </div> </div> <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> <button type="submit" value="Update Profile" class="btn btn-info btn-fill pull-right">Update Profile</button> <div class="clearfix"></div> </form>

Estoy tratando de explicar esto de una manera que los principiantes puedan encontrar más fácil de entender. Preste mucha atención al else:

photo = user_extended.photo first_name = user.first_name last_name = user.last_name address = user_extended.address phoneNumber = user_extended.phoneNumber form = EditProfileForm( initial={''first_name'': first_name, ''last_name'': last_name, ''address'': address, ''phoneNumber'': phoneNumber, ''photo'': photo})

Es lo que obtiene el valor de atributo, por ejemplo:

<p><label for="id_first_name">First Name:</label> <input class="form-control" id="id_first_name" name="first_name" type="text" value="Emmanuel" /></p> <p><label for="id_last_name">Last Name:</label> <input class="form-control" id="id_last_name" name="last_name" type="text" value="Castor" /></p>


Puedes hacer esto desde la plantilla con algo como esto:

{% if form.instance.some_field %} {{form.instance.some_field}} {% else %} {{form.data.some_field}} {% endif %}

Esto mostrará el valor de la instancia (si el formulario se crea con una instancia, puede usar inicial en su lugar si lo desea), o bien mostrar los datos de la POST, como cuando se produce un error de validación.


Quería mostrar el valor de un campo formset. Concluí esta solución, que también debería funcionar para formas normales:

{% if form.email.data %} {{ form.email.data }} {% else %} {{ form.initial.email }} {% endif %}

Las soluciones anteriores no funcionaron muy bien para mí, y dudo que funcionen en el caso de formas prefijadas (como asistentes y formularios). Las soluciones que usan {{ form.data.email }} no pueden funcionar, porque es una búsqueda de diccionario, y con formas prefijadas su nombre de campo se vería como ''1-email'' (asistente y forma prefijada) o ''form- 1-email ''(formset), y el signo menos (-) no están permitidos en las expresiones de búsqueda de plantillas de puntos.

{{form.field_name.value}} es solo Django 1.3+.


Si ha llenado el formulario con una instancia y no con datos POST (como requiere la respuesta sugerida), puede acceder a los datos utilizando {{form.instance.my_field_name}}.


Tengo una solución simple para ti!

{{ form.data.email }}

Probé esto y funcionó. Esto requiere que su vista rellene la clase de formulario con los datos POST.

Ejemplo muy simple:

def your_view(request): if request.method == ''POST'': form = YourForm(request.POST) if form.is_valid(): # some code here else: form = YourForm() return render_to_response(''template.html'', {''form'':form})

Espero que te ayude. Si tiene alguna pregunta, por favor hágamelo saber.


{{form.field_name.value}} funciona para mí


{{form.fields.email}}