[Django]-How to set and get cookies in Django?

87👍

UPDATE : check Peter’s answer below for a builtin solution :

This is a helper to set a persistent cookie:

import datetime

def set_cookie(response, key, value, days_expire=7):
    if days_expire is None:
        max_age = 365 * 24 * 60 * 60  # one year
    else:
        max_age = days_expire * 24 * 60 * 60
    expires = datetime.datetime.strftime(
        datetime.datetime.utcnow() + datetime.timedelta(seconds=max_age),
        "%a, %d-%b-%Y %H:%M:%S GMT",
    )
    response.set_cookie(
        key,
        value,
        max_age=max_age,
        expires=expires,
        domain=settings.SESSION_COOKIE_DOMAIN,
        secure=settings.SESSION_COOKIE_SECURE or None,
    )

Use the following code before sending a response.

def view(request):
    response = HttpResponse("hello")
    set_cookie(response, 'name', 'jujule')
    return response

UPDATE : check Peter’s answer below for a builtin solution :

👤jujule

308👍

Using Django’s session framework should cover most scenarios, but Django also now provide direct cookie manipulation methods on the request and response objects (so you don’t need a helper function).

Setting a cookie:

def view(request):
  response = HttpResponse('blah')
  response.set_cookie('cookie_name', 'cookie_value')

Retrieving a cookie:

def view(request):
  value = request.COOKIES.get('cookie_name')
  if value is None:
    # Cookie is not set

  # OR

  try:
    value = request.COOKIES['cookie_name']
  except KeyError:
    # Cookie is not set
👤Peter

19👍

You could manually set the cookie, but depending on your use case (and if you might want to add more types of persistent/session data in future) it might make more sense to use Django’s sessions feature. This will let you get and set variables tied internally to the user’s session cookie. Cool thing about this is that if you want to store a lot of data tied to a user’s session, storing it all in cookies will add a lot of weight to HTTP requests and responses. With sessions the session cookie is all that is sent back and forth (though there is the overhead on Django’s end of storing the session data to keep in mind).

6👍

Anyone interested in doing this should read the documentation of the Django Sessions framework. It stores a session ID in the user’s cookies, but maps all the cookies-like data to your database. This is an improvement on the typical cookies-based workflow for HTTP requests.

Here is an example with a Django view …

def homepage(request):

    request.session.setdefault('how_many_visits', 0)
    request.session['how_many_visits'] += 1

    print(request.session['how_many_visits'])

    return render(request, 'home.html', {})

If you keep visiting the page over and over, you’ll see the value start incrementing up from 1 until you clear your cookies, visit on a new browser, go incognito, or do anything else that sidesteps Django’s Session ID cookie.

0👍

In addition to jujule’s answer below you can find a solution that shows how to set a cookie to Class Based Views responses. You can apply this solution to your view classes that extends from TemplateView, ListView or View.

Below a modified version of jujule’s persistent cookie setter method:

import datetime

from django.http import HttpResponse


def set_cookie(
    response: HttpResponse,
    key: str,
    value: str,
    cookie_host: str,
    days_expire: int = 365,
):
    max_age = days_expire * 24 * 60 * 60
    expires = datetime.datetime.strftime(
        datetime.datetime.utcnow() + datetime.timedelta(days=days_expire), "%a, %d-%b-%Y %H:%M:%S GMT",
    )
    domain = cookie_host.split(":")[0]
    response.set_cookie(
        key,
        value,
        max_age=max_age,
        expires=expires,
        domain=domain,
        secure=False,
    )

And sample class based view example that adds a cookie using persistent cookie setter

class BaseView(TemplateView):
    template_name = "YOUR_TEMPLATE_FILE_PATH"

    def get(self, request, *args, **kwargs):
        response = super().get(request, *args, **kwargs)
        set_cookie(
            response=response,
            key="COOKIE_KEY",
            value="COOKIE_VALUE",  
            cookie_host=request.get_host(),
            days_expire=7,
        )
        return response

0👍

You can set cookies 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 question and my answer which explain why to use response.set_cookie() rather than response.cookies[] to set cookies and I asked the question about how to set a dictionary or list to a cookie and get it properly and you can see my answer explaining how to delete cookies.

render() and set_cookie():

from django.shortcuts import render

def my_view(request):
    response = render(request, 'index.html', {})
    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):
    rts = render_to_string('index.html', {})
    response = HttpResponse(rts)
    response.set_cookie('name', 'John')
    response.cookies['age'] = 27
    return response # Must return the object

HttpResponse() and set_cookie():

from django.http import HttpResponse

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

redirect() and set_cookie():

from django.shortcuts import redirect

def my_view(request):
    response = redirect('https://example.com/')
    response.set_cookie('name', 'John')
    response.cookies['age'] = 27
    return response # Must return the object

HttpResponseRedirect() and set_cookie():

from django.http import HttpResponseRedirect

def my_view(request):
    response = HttpResponseRedirect('https://example.com/')
    response.set_cookie('name', 'John')
    response.cookies['age'] = 27
    return response # Must return the object

And, you can get the cookies with request.COOKIES[‘key’] and request.COOKIES.get(‘key’) as shown below. *request.COOKIES.get() returns None by default if the key doesn’t exist and you can change None to other value like Doesn't exist by setting it to the 2nd argument as shown below:

from django.shortcuts import render

def my_view(request):
    print(request.COOKIES['name']) # John
    print(request.COOKIES.get('age')) # 27
    print(request.COOKIES.get('gender')) # None
    print(request.COOKIES.get('gender', "Doesn't exist")) # Doesn't exist
    return render(request, 'index.html', {})

And, you can get cookies with request.COOKIES.key in Django Templates as shown below:

# "templates/index.html"

{{ request.COOKIES.name }} {# John #}
{{ request.COOKIES.age }} {# 27 #}

And, you can delete the cookies with response.delete_cookie() as shown below. *You must return the object otherwise cookies are not deleted from a browser:

from django.shortcuts import render

def my_view(request):
    response = render(request, 'index.html', {})
    response.delete_cookie('name')
    response.delete_cookie('age')
    return response # Must return the object

Leave a comment