How to set cookie and render template in Django?
Asked Answered
J

6

28

I want to set a cookie inside a view and then have that view render a template. As I understand it, this is the way to set a cookie:

def index(request):
    response = HttpResponse('blah')
    response.set_cookie('id', 1)
    return response

However, I want to set a cookie and then render a template, something like this:

def index(request, template):
    response_obj = HttpResponse('blah')
    response_obj.set_cookie('id', 1)
    return render_to_response(template, response_obj)   # <= Doesn't work

The template will contain links that when clicked will execute other views that check for the cookie I'm setting. What's the correct way to do what I showed in the second example above? I understand that I could create a string that contains all the HTML for my template and pass that string as the argument to HttpResponse but that seems really ugly. Isn't there a better way to do this? Thanks.

Jacktar answered 12/6, 2013 at 4:10 Comment(0)
J
40

This is how to do it:

from django.shortcuts import render

def home(request, template):
    response = render(request, template)  # django.http.HttpResponse
    response.set_cookie(key='id', value=1)
    return response
Jacktar answered 27/6, 2013 at 4:57 Comment(4)
You first instantiate a HttpResponse but do nothing with it. render returns a response, which you assign into the same variable on which you then set the cookie and which you finally return. Your answer would be equivalent with the line response = HttpResponse() removed.Leticia
I may have misunderstood something, but wasn't the question "how to set a cookie before rendering the template"?Seaton
@Seaton that's how the question may have been phrased, but I can't think of any use cases where it makes a difference whether the cookie is set before or after the rendering. As long as it goes out with the response, all the downstream logic would be blind to the ordering.Citadel
@DrPhil A wild guess about the usecase would be to render a cookie value in the template for whatever reason. I'm unsure about the safety concerns or about the good practices though. But the behavior would be different.Seaton
S
6

If you just need the cookie value to be set when rendering your template, you could try something like this :

def view(request, template):
    # Manually set the value you'll use for rendering
    # (request.COOKIES is just a dictionnary)
    request.COOKIES['key'] = 'val'
    # Render the template with the manually set value
    response = render(request, template)
    # Actually set the cookie.
    response.set_cookie('key', 'val')

    return response
Seaton answered 22/6, 2016 at 2:37 Comment(0)
P
5

The accepted answer sets the cookie before the template is rendered. This works.

response = HttpResponse()
response.set_cookie("cookie_name", "cookie_value")
response.write(template.render(context))
Paradies answered 29/4, 2016 at 9:48 Comment(0)
C
0
                response = render(request, 'admin-dashboard.html',{"email":email})
                #create cookies
                expiry_time = 60 * 60 #in seconds
                response.set_cookie("email_cookie",email,expiry_time);
                response.set_cookie("classname","The easylearn academy",expiry_time);
Crooks answered 11/8, 2021 at 8:49 Comment(0)
I
0

You can set cookies and render a template in these ways as shown below. *You must return the object otherwise cookies are not set to a browser different from Django sessions which can set the session id cookies to a browser without returning the object and you can see my answer explaining how to set and get cookies in Django.

render() and set_cookie():

from django.shortcuts import render

def my_view(request, template):
    response = render(request, template)
    response.set_cookie('name', 'John')
    response.cookies['age'] = 27
    return response # Must return the object

render_to_string(), HttpResponse() and set_cookie():

from django.template.loader import render_to_string
from django.http import HttpResponse

def my_view(request, template):
    rts = render_to_string(template)
    response = HttpResponse(rts)
    response.set_cookie('name', 'John')
    response.cookies['age'] = 27
    return response # Must return the object set
Isomorph answered 2/7, 2023 at 16:28 Comment(0)
D
-1
def index(request, template):
    response = HttpResponse('blah')
    response.set_cookie('id', 1)
    id = request.COOKIES.get('id')
    return render_to_response(template,{'cookie_id':id})
Darreldarrell answered 12/6, 2013 at 4:25 Comment(5)
Then in your template you can show the links based on whether your cookie is set or not. Ex: {% if cookie_id %} #links to be displayed {%endif%}Darreldarrell
Thank you for responding. However, this doesn't look right. Your code is looking for a cookie called 'id' in the request. However, the cookie isn't being set until after that request was received so it's not going to be there.Jacktar
I guess one simple way to do it would be just to run some JavaScript on the client side when the template is rendered that creates the cookie. But I'm still curious as to whether what I'm asking about above can be done server-side.Jacktar
I'm not getting an error but the code you showed doesn't work, I think for the reason I described.Jacktar
try this id = request.COOKIES.get('id',None)Darreldarrell

© 2022 - 2024 — McMap. All rights reserved.