django-oscar / django-oscar-api

RESTful JSON API for django-oscar

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

basket endpoint conflicts with Django's UpdateCacheMiddleware: {TypeError}cannot pickle '_io.BufferedReader' object

ViggieM opened this issue · comments

I implemented django's per site cache in a django-oscar project with django-oscar-api. I use LocMemCache as a cache backend.

Before adding django.middleware.cache.UpdateCacheMiddleware to my middlewares, everything worked fine and I could make a request to the "basket" endpoint like this and it returned a 200 response:

import requests

session = session.Session()
r_basket = session.get("http://127.0.0.1:8000/api/basket/")

After adding the per-site caching the response has the status code 500. I debugged it and it fails in the UpdateCacheMiddleware with the following error: {TypeError}cannot pickle '_io.BufferedReader' object.

Other endpoints seem to work fine, but I haven't tested them all yet. The error can also be reproduced on a freshly installed django-oscar sandbox. I pip-installed the django-oscar-api and added it to the installed apps, and the MIDDLEWARE setting looks like this:

MIDDLEWARE = [
    'debug_toolbar.middleware.DebugToolbarMiddleware',

    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',

    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware',

    # Allow languages to be selected
    'django.middleware.locale.LocaleMiddleware',
    'django.middleware.http.ConditionalGetMiddleware',
    'django.middleware.common.CommonMiddleware',

    # per site caching
    'django.middleware.cache.UpdateCacheMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.cache.FetchFromCacheMiddleware',

    # Ensure a valid basket is added to the request instance for every request
    'oscar.apps.basket.middleware.BasketMiddleware',
]

My package versions are Django v.3.2.9, django-oscar v.2.2 or 3.0, django-oscar-api v.2.1.1.

Problem fixed, the caching middlewares must come before the SessionMiddleware.