6


Django(および一般的に)では、Cookieはヘッダーでもあります。たとえば、User-Agent
つまり、これら2つの方法はDjangoで同等ですか?

使用set_cookie

response.set_cookie('food', 'bread')
response.set_cookie('drink', 'water')

ヘッダー設定の使用:

response['Cookie'] = ('food=bread; drink=water')
# I'm not sure whether 'Cookie' should be capitalized or not


また、2番目の方法を使用してCookieを設定できる場合、文字列に、
などの追加情報を含めるにはどうすればよいですか?それらを特殊 文字で分離しませんか?pathmax_age


4

3 に答える 3

7

を使えばもっと楽になりますset_cookie。しかし、はい、応答ヘッダーを設定することで Cookie を設定できます。

response['Set-Cookie'] = ('food=bread; drink=water; Path=/; max_age=10')

ただし、オブジェクトをリセットするSet-Cookieと前のものがクリアされるため、Djangoresponseで複数のヘッダーを使用することはできません。Set-Cookie理由を見てみましょう。

response.py、set_cookieメソッドで観察します:

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

ここで注意すべき点が 2 つあります。

  1. set_cookieメソッドによって処理datetimeが行われexpires 、自分で設定する場合は自分で設定する必要があります。
  2. self.cookie辞書の辞書です。そのため、すぐにわかるように、それぞれkeyがヘッダーに a を追加します。["Set-Cookie"]

cookies内部のオブジェクトHttpResponseは に渡され WSGIHandler、応答ヘッダーに追加されます。

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=''))))

上記のコードは、応答ヘッダーでset_cookie()複数のみを許可する理由でもあり、Cookie をオブジェクトにSet-Cookie直接設定すると1 つだけが返されます。ResponseSet-Cookie

于 2013-02-28T02:06:00.907 に答える
1

わかりましたが、「Cookie」を「Set-Cookie」に変更し、「Path=/」を追加してサイト全体にします。

response["Set-Cookie"] = "food=bread; drink=water; Path=/"

編集:

これを自分で試してみたところ、興味深い癖が見つかりましたset_cookie。同じヘッダーで同様の Cookie (同じパス、有効期限、ドメインなど) をグループ化していません。別の「Set-Cookie」を応答に追加するだけです。文字列のチェックといじりは、おそらくHTTPヘッダーに数バイト余分にあるよりも時間がかかるため、理解できます(そして、せいぜいマイクロ最適化です)。

response.set_cookie("food",  "kabanosy")
response.set_cookie("drink", "ardbeg")
response.set_cookie("state", "awesome")

# result in these headers
#   Set-Cookie: food=kabonosy; Path=/
#   Set-Cookie: drink=ardbeg; Path=/
#   Set-Cookie: state=awesome; Path=/

# not this
#   Set-Cookie:food=kabanosy; drink=ardbeg; state=awesome; Path=/
于 2013-02-27T23:18:14.290 に答える
1

HttpResponseクラスのコードからのスニペット:

class HttpResponse(object):

    #...

    def __init__(self, content='', mimetype=None, status=None,

        #...

        self.cookies = SimpleCookie()

    #...

    def set_cookie(self, key, value='', max_age=None, expires=None, path='/',
                   domain=None, secure=False, httponly=False):

        self.cookies[key] = value

        #...


つまり、response.set_cookie()が呼び出されるたびに、新しい Cookie
valueを配置するかresponse.cookies[key]、そのキーに既存の値がある場合はその値を変更します。複数のヘッダー
を設定する理由を説明します。 どうすれば で同じことができるのだろうか。Set-Cookie
response['Set-Cookie']

于 2013-02-28T00:36:47.823 に答える