Max Larrain February 2016

Context Variable will not show up in Django template

I am writing a blog application, and a variable will not show up when the page is rendered. Here is my views.py function for my blog app:

def post_share(request, post_id):
    # retrieves post by id
    post = get_object_or_404(Post, id=post_id, status='published')
    sent = False

    if request.method == 'POST':
        # FORM was submitted
        form = EmailPostForm(request.POST)
        if form.is_valid():
            # form fields passed validation
            cd = form.cleaned_data

            post_url = request.build_absolute_uri(post.get_absolute_url())                                          
            subject = '{} ({}) recommends you reading "{}"'.format(cd['name'], cd['email'], post.title)
            message = 'Read "{}" at {}\n\n{}\'s comments: {}'.format(post.title, post_url, cd['name'], cd['comments'])

            send_mail(subject, message, 'admin@myblog.com', [cd['to']])
            sent = True

    else:
        form = EmailPostForm()
    return render(request, 'blog/post/share.html', {'post': post,
                                                'form': form,
                                                'sent': sent})

And forms.py:

from django import forms
from .models import Comment

class EmailPostForm(forms.Form):
    name = forms.CharField(max_length=25)
    email = forms.EmailField()
    to = forms.EmailField()
    comments = forms.CharField(required=False, widget=forms.Textarea)

Relevant part of my HTML template:

{% block content %}
    {% if sent %}
        <h1> Email successfully sent </h1>
        <p>
            "{{ post.title }}" was successfully sent to {{ cd.to }} .
        </p>
    {% else %}
        <h1> Share "{{ post.title }}" by email</h1>
        <form action="." method="post">
            {{ form.as_p }}
            {% csrf_token %}
            <input type="sub        

Answers


Leistungsabfall February 2016

cd is only used within your view, but it is not a context variable.

To make it a context variable and accessible in the template you have to add it to your existing context variables:

return render(request, 'blog/post/share.html', {'post': post,
                                            'form': form,
                                            'sent': sent,
                                            'cd': cd})


djq February 2016

You need to add to or cd to your context:

return render(request, 'blog/post/share.html', {'post': post,
                                                'form': form,
                                                'sent': sent})

For example:

{'cd': cd,
 'post': post,
 'form': form,
  'sent': sent}


Alasdair February 2016

You need to include the cleaned data in the template context. However, cd is only defined when the form is valid, so you can do something like:

data = {
    'post': post,
    'form': form,
    'sent': sent,
}

if sent:
    data['cd'] = cd
return render(request, 'blog/post/share.html', data)

Since you don't need the entire cd dictionary in the template, another option would be to pass only the variable you need, cd['to'].

data = {
    'post': post,
    'form': form,
    'sent': sent,
}

if sent:
    data['sent_to'] = cd['to']
return render(request, 'blog/post/share.html', data)

Then in your template, you would use {{ sent_to }} instead of {{ cd.to }}

Post Status

Asked in February 2016
Viewed 3,764 times
Voted 11
Answered 3 times

Search




Leave an answer