Django Cookies, jak mogę je ustawić?

123

Mam witrynę internetową, która przedstawia różne treści w zależności od lokalizacji wybranej przez użytkownika. np .: Użytkownik wprowadza kod 55812 jako kod pocztowy. Wiem, w jakim mieście i na jakim obszarze lat / długo. to znaczy i przekazać im treść dotyczącą tego obszaru. Moje pytanie brzmi: jak mogę to zapisać w pliku cookie, aby po powrocie nie musieli zawsze wpisywać swojego kodu pocztowego?

Widzę to następująco:

  1. Ustaw trwałe pliki cookie na podstawie ich obszaru.
  2. Kiedy wrócą, przeczytaj plik cookie, pobierz kod pocztowy.
  3. Zwróć zawartość na podstawie kodu pocztowego w pliku cookie.

Nie mogę znaleźć żadnych rzetelnych informacji na temat tworzenia plików cookie. Każda pomoc jest mile widziana.

Jeffrey
źródło
Ci, którzy szukają miejsca cookiei rendering a templaterazem, zobacz odpowiedź.
TheGuardener

Odpowiedzi:

67

AKTUALIZACJA : sprawdź odpowiedź Petera poniżej, aby uzyskać wbudowane rozwiązanie:

To jest pomocnik do ustawienia trwałego pliku 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)

Użyj poniższego kodu przed wysłaniem odpowiedzi.

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

AKTUALIZACJA : sprawdź odpowiedź Petera poniżej, aby uzyskać wbudowane rozwiązanie:

jujule
źródło
jakiś problem, jeśli settings.SESSION_COOKIE_DOMAIN nie jest ustawione?
panchicore
1
w każdym razie django samo ustawia domyślną SESSION_COOKIE_DOMAIN. pomyśl o tym ustawieniu, jeśli chcesz udostępniać pliki cookie w wielu subdomenach.
jujule
12
-1 w tym, django zawiera metodę ustawiania plików cookie docs.djangoproject.com/en/dev/ref/request-response/ ...
fetzig
2
@klemens: tak i wreszcie wywołałem metodę django w moim przykładzie; to tylko skrót (od 2009 roku), który upraszcza przetwarzanie danych.
jujule
5
nie obchodzi mnie to, ale fyi: bezużyteczna funkcja pomocnicza była już bezużyteczna w 2009 roku. docs.djangoproject.com/en/1.0/ref/request-response/ ... (django 1.0 został wydany we wrześniu 2008 roku, o ile wiem)
fetzig
259

Używanie struktury sesji Django powinno obejmować większość scenariuszy, ale Django zapewnia teraz również metody bezpośredniej manipulacji plikami cookie na obiektach żądań i odpowiedzi (więc nie potrzebujesz funkcji pomocniczej).

Ustawienie pliku cookie:

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

Pobieranie pliku 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
Piotr
źródło
10
Tylko do aktualizacji - „has_key” został zastąpiony przez „in”.
skaz
15
Bardziej pythonowym sposobem byłoby wywołanie request.COOKIES.get ('cookie_name')
Charlesthk
pozwól, że zadam ci głupie pytanie, te pliki cookie pozostają między sesjami innych zastosowań?
Diego Vinícius
Nie ma tu nic wartościowego do dodania, ale gdy istnieją rozwiązania ramowe, często lepiej jest ich używać niż używać niestandardowych funkcji pomocniczych do tego zadania, zwłaszcza jeśli nie ma powodu, aby tego nie robić. Te rozwiązania być może początkowo nie były dostępne, ale na pewno są, więc dlaczego z nich nie skorzystać? Tworzy to prostszy kod i może obsługiwać więcej przypadków niż to, co pomyśleliby o obsłudze naszych niestandardowych pomocników, co samo w sobie jest dobrym argumentem.
vincent-lg
2
Jeśli zastanawiasz się, jak utworzyć obiekt odpowiedzi Django z obiektu żądania Django, przeczytaj to: stackoverflow.com/questions/17057536/ ...
critikaster
19

Możesz ręcznie ustawić plik cookie, ale w zależności od twojego przypadku użycia (i jeśli możesz chcieć dodać więcej typów danych trwałych / sesji w przyszłości), bardziej sensowne może być użycie funkcji sesji Django . To ci pozwoli uzyskać i ustawić zmienne powiązane wewnętrznie z plikiem cookie sesji użytkownika. Fajne w tym jest to, że jeśli chcesz przechowywać dużo danych związanych z sesją użytkownika, przechowywanie ich wszystkich w plikach cookie doda dużo wagi żądaniom i odpowiedziom HTTP. W przypadku sesji plik cookie sesji to wszystko, co jest przesyłane tam iz powrotem (chociaż należy pamiętać o narzutach związanych z przechowywaniem danych sesji przez Django).

Ben Regenspan
źródło
4
Słuszna uwaga! Jedna uwaga, możesz zmniejszyć wagę HTTP, przechowując statyczną zawartość w oddzielnej domenie (nie subdomenie), aby pliki cookie nie były wysyłane w tych żądaniach. stackoverflow.com/questions/72394/…
John Paulett
Komentarz @ JohnPaulett jest nieaktualny, biorąc pod uwagę istnienie frameworka Django Sessions. Nie powinno już być potrzeby minimalizowania całkowitego przechowywania danych w przepływach pracy opartych na plikach cookie.
Chris Conlan
0

Każdy, kto jest zainteresowany zrobieniem tego, powinien przeczytać dokumentację frameworka Django Sessions . Przechowuje identyfikator sesji w plikach cookie użytkownika, ale mapuje wszystkie dane podobne do plików cookie w Twojej bazie danych. Jest to ulepszenie typowego przepływu pracy opartego na plikach cookie dla żądań HTTP.

Oto przykład z widokiem Django ...

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', {})

Jeśli będziesz odwiedzać tę stronę w kółko, zobaczysz, że wartość zaczyna rosnąć od 1 do momentu wyczyszczenia plików cookie, wizyty w nowej przeglądarce, przejścia w tryb incognito lub zrobienia czegokolwiek innego, co pomija plik cookie z identyfikatorem sesji Django.

Chris Conlan
źródło