Sẽ dễ dàng hơn nhiều nếu bạn sử dụng set_cookie
. Nhưng có, bạn có thể đặt cookie của thiết lập các tiêu đề phản ứng:
response['Set-Cookie'] = ('food=bread; drink=water; Path=/; max_age=10')
Tuy nhiên, kể từ khi thiết lập lại Set-Cookie
trong response
đối tượng sẽ rõ ràng ra trước một, bạn không thể có nhiều hơn một Set-Cookie
tiêu đề trong Django. Hãy xem lý do.
Quan sát trong response.py, set_cookie
method:
class HttpResponseBase:
def __init__(self, content_type=None, status=None, mimetype=None):
# _headers is a mapping of the lower-case name to the original case of
# the header (required for working with legacy systems) and the header
# value. Both the name of the header and its value are ASCII strings.
self._headers = {}
self._charset = settings.DEFAULT_CHARSET
self._closable_objects = []
# This parameter is set by the handler. It's necessary to preserve the
# historical behavior of request_finished.
self._handler_class = None
if mimetype:
warnings.warn("Using mimetype keyword argument is deprecated, use"
" content_type instead",
DeprecationWarning, stacklevel=2)
content_type = mimetype
if not content_type:
content_type = "%s; charset=%s" % (settings.DEFAULT_CONTENT_TYPE,
self._charset)
self.cookies = SimpleCookie()
if status:
self.status_code = status
self['Content-Type'] = content_type
...
def set_cookie(self, key, value='', max_age=None, expires=None, path='/',
domain=None, secure=False, httponly=False):
"""
Sets a cookie.
``expires`` can be:
- a string in the correct format,
- a naive ``datetime.datetime`` object in UTC,
- an aware ``datetime.datetime`` object in any time zone.
If it is a ``datetime.datetime`` object then ``max_age`` will be calculated.
"""
self.cookies[key] = value
if expires is not None:
if isinstance(expires, datetime.datetime):
if timezone.is_aware(expires):
expires = timezone.make_naive(expires, timezone.utc)
delta = expires - expires.utcnow()
# Add one second so the date matches exactly (a fraction of
# time gets lost between converting to a timedelta and
# then the date string).
delta = delta + datetime.timedelta(seconds=1)
# Just set max_age - the max_age logic will set expires.
expires = None
max_age = max(0, delta.days * 86400 + delta.seconds)
else:
self.cookies[key]['expires'] = expires
if max_age is not None:
self.cookies[key]['max-age'] = max_age
# IE requires expires, so set it if hasn't been already.
if not expires:
self.cookies[key]['expires'] = cookie_date(time.time() +
max_age)
if path is not None:
self.cookies[key]['path'] = path
if domain is not None:
self.cookies[key]['domain'] = domain
if secure:
self.cookies[key]['secure'] = True
if httponly:
self.cookies[key]['httponly'] = True
Hai điều cần lưu ý ở đây:
set_cookie
phương pháp sẽ chăm sóc xử lý datetime
trong expires
cho bạn, và bạn sẽ phải cài đặt nó cho mình nếu bạn tự đặt nó.
self.cookie
là từ điển của dictionaies. Vì vậy, mỗi key
sẽ thêm ["Set-Cookie"]
vào tiêu đề, như bạn sẽ thấy ngay.
Đối tượng cookies
bên HttpResponse
sau đó sẽ được thông qua để WSGIHandler
, và được nối vào tiêu đề phản ứng:
response_headers = [(str(k), str(v)) for k, v in response.items()]
for c in response.cookies.values():
response_headers.append((str('Set-Cookie'), str(c.output(header=''))))
Đoạn mã trên cũng là lý do tại sao chỉ set_cookie()
phép nhiều Set-Cookie
trong tiêu đề phản ứng, và cài đặt cookie đó trực tiếp đến đối tượng Response
sẽ chỉ trả lại một Set-Cookie
.
Vì vậy, nếu tôi đặt hai cookie khác nhau, với các tham số 'đường dẫn' và' max_age' khác nhau; nhưng sử dụng cú pháp 'response [" Set-Cookie "] = ...'? –
Thành thật mà nói, bạn nên sử dụng 'set_cookie' vì không có lợi ích thực sự nào từ việc tự đặt tiêu đề. Nó sẽ giống như thế này: 'response [" Set-Cookie "] =" food = kabanosy; Max-Age = 86400; Path =/"'. – Matt
Tôi biết về cơ bản thuận tiện hơn khi sử dụng 'set_cookie', nhưng tôi muốn hiểu mối quan hệ của nó với đối tượng' HttpResponse' và với tiêu đề. –