How do I display the value of a Django form field in a template?

DjangoDjango Templates

Django Problem Overview


I have a form with an email property.

When using {{ form.email }} in case of some validation error, Django still renders the previous value in the input tag's value attribute:

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

I want to render the input tag myself (to add some JavaScript code and an error class in case of an error). For example this is my template instead of {{ form.email }}:

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

However, this does not display the erroneous value ([email protected] in this example) to the user.

How do I get the field's value in the template?

Django Solutions


Solution 1 - Django

This was a feature request that got fixed in Django 1.3.

Here's the bug: https://code.djangoproject.com/ticket/10427

Basically, if you're running something after 1.3, in Django templates you can do:

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

Or in Jinja2:

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

Note that field.value() is a method, but in Django templates ()'s are omitted, while in Jinja2 method calls are explicit.

If you want to know what version of Django you're running, it will tell you when you do the runserver command.

If you are on something prior to 1.3, you can probably use the fix posted in the above bug: https://code.djangoproject.com/ticket/10427#comment:24

Solution 2 - Django

You can do this from the template with something like this:

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

This will display the instance value (if the form is created with an instance, you can use initial instead if you like), or else display the POST data such as when a validation error occurs.

Solution 3 - Django

This seems to work.

{{ form.fields.email.initial }}

Solution 4 - Django

I have a simple solution for you!

{{ form.data.email }}

I tried this and it worked. This requires your view to populate the form class with the POST data.

Very simple example:

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})

Hope that helps you. If you have any questions please let me know.

Solution 5 - Django

{{ form.field_name.value }} works for me

Solution 6 - Django

The solution proposed by Jens is correct. However, it turns out that if you initialize your ModelForm with an instance (example below) django will not populate the data:

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)

So, I made my own ModelForm base class that populates the initial data:

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)

Then, the simple view example looks like this:

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()

Solution 7 - Django

I tried a few of the mentioned possibilities, and this is how I solved my problem:

#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>

I am trying to explain this in a way so that beginners may find it easier to understand. Pay close attention to the 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}) 

It is what gets the value attrib, e.g.:

<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>

Solution 8 - Django

If you've populated the form with an instance and not with POST data (as the suggested answer requires), you can access the data using {{ form.instance.my_field_name }}.

Solution 9 - Django

I wanted to display the value of a formset field. I concluded this solution, which should work for normal forms too:

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

The above solutions didn't worked very well for me, and I doubt they would work in case of prefixed forms (such as wizards and formsets). The solutions using {{ form.data.email }} can't work, because it is a dictionary lookup, and with prefixed forms your field name would look something like '1-email' (wizard and prefixed form) or 'form-1-email' (formset), and the minus sign (-) are not allowed in dotted template lookup expressions.

{{form.field_name.value}} is Django 1.3+ only.

Solution 10 - Django

On Django 1.2, {{ form.data.field }} and {{ form.field.data }} are all OK, but not {{ form.field.value }}.
As others said, {{ form.field.value }} is Django 1.3+ only, but there's no specification in https://docs.djangoproject.com/en/1.3/topics/forms/. It can be found in https://docs.djangoproject.com/en/1.4/topics/forms/.

Solution 11 - Django

For check box with its items:

{% for item in people.q %}
    <div class="form-check form-switch ">
    <label class="form-check-label" for="{{ item.id_for_label }}">{{ item.data.label }}</label>
    <input class="form-check-input" type="checkbox" id="{{ item.id_for_label }}" value="{{ item.data.value }}">
     </div>
{% endfor %}

q is field name.

Solution 12 - Django

{{form.fields.email}}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEran KampfView Question on Stackoverflow
Solution 1 - DjangomlissnerView Answer on Stackoverflow
Solution 2 - DjangoLeeMobileView Answer on Stackoverflow
Solution 3 - DjangoRichView Answer on Stackoverflow
Solution 4 - DjangoJensView Answer on Stackoverflow
Solution 5 - DjangorobertzpView Answer on Stackoverflow
Solution 6 - DjangoEran KampfView Answer on Stackoverflow
Solution 7 - DjangoDurodola OpemipoView Answer on Stackoverflow
Solution 8 - DjangomonofonikView Answer on Stackoverflow
Solution 9 - DjangokosiiView Answer on Stackoverflow
Solution 10 - DjangobigwindView Answer on Stackoverflow
Solution 11 - DjangonamjooView Answer on Stackoverflow
Solution 12 - DjangoshanyuView Answer on Stackoverflow