在Django视图中设置cookie的最佳方法?

时间:2018-05-14 21:12:19

标签: python django

我正在修改类似于以下内容的Django视图:

class ListBase(DashboardAccessMixin, OrderingMixin, FilterMixin, SearchMixin):

    def get(self, request, *args, **kwargs):
        if should_delete_filter_cookie(request, path=reverse('dashboard:families')):
            request.COOKIES.pop('filters', None)

        self.query_dict = query_dict_from_params_or_cookies(request)

        return super().get(request, *args, **kwargs)

    def render_to_response(self, context, **response_kwargs):
        response = super().render_to_response(context, **response_kwargs)

        path = reverse('dashboard:families')

        if should_delete_filter_cookie(self.request, path=path):
            response.delete_cookie('filters', path=path)
        elif list(self.request.GET.items()):
            response.set_cookie('filters', self.request.GET.urlencode(), path=path)

        return response

辅助函数should_delete_filter_cookiequery_dict_from_params_or_cookies定义为

def query_dict_from_params_or_cookies(request):
    query_dict = request.GET

    cookie_filters = request.COOKIES.get('filters')

    if cookie_filters and not list(query_dict.items()):
        query_dict = QueryDict(cookie_filters)

    return query_dict


def should_delete_filter_cookie(request, path):
    referer_path = urlparse(request.META.get('HTTP_REFERER')).path

    if referer_path and path not in referer_path:
        return True
    else:
        return False

该视图包含filter_formsearch_form(通过相应的mixins),它们与self.query_dict绑定。此外,我们遵循命名惯例,即UpdateViewCreateView的网址只是ListView网址的“扩展名”:例如,前者为{{1而后者只是/dashboard/families(但不是dashboard/families/1)。

dashboard/family/1现在是这样的,当您从ListView返回时,它会通过从Cookie中获取UpdateView来保留之前应用的过滤器。

我想知道为什么在self.query_dict方法和should_delete_filter_cookie方法中调用get()两次。仅仅这样做一次还不够吗?

另外,render_to_response()方法中为什么response.set_cookie使用render_to_response而不是request.COOKIES['filters'] = request.GET.urlencode()方法中仅使用get()

在更基础的层面上,我很难理解request.COOKIESresponse.cookies之间的区别。例如,在以下测试用例中,

from django.test import SimpleTestCase, RequestFactory
from django.urls import reverse
from http.cookies import SimpleCookie


class SearchFilterTest(SimpleTestCase):
    def setUp(self):
        # Use a RequestFactory instead of a Client to obtain Request objects instead of Response objects
        self.factory = RequestFactory()

    def test_get_with_cookies(self):
        self.client.cookies = SimpleCookie({'filters': 'q=Christine'})
        response = self.client.get(
            reverse('dashboard:families'),
            HTTP_REFERER=reverse('dashboard:family', kwargs={'pk': 1, 'tab': 'case-management'}))
        import ipdb; ipdb.set_trace()

如果我进入调试器,我看到response.cookies为空SimpleCookie,即使已为测试客户端设置了cookie:

ipdb> response.cookies
<SimpleCookie: >

response.cookies仅代表使用response.set_cookie设置的Cookie,而不代表原始请求附带的Cookie吗?

此外,使用get()render_to_response()方法在此用例中设置Cookie的最佳方法是什么?

0 个答案:

没有答案