Django кэширует изображение из внешнего API - PullRequest
1 голос
/ 03 июля 2019

Я хочу кэшировать изображения, которые приходят в мое приложение из Google API.

Настройки (обратите внимание, что я предпочитаю использовать FileBasedCache):

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
        'LOCATION': CACHE_ROOT,
        'TIMEOUT': 0,
    }
}

Вот мой код, который вызывается всякий раз, когда я хочу получить любую фотографию:

    # Shorting later syntaxes
    photo_ref = photo["photo_reference"]
    # Setting up cache key
    cache_key = "PHOTO_IMAGE" + photo_ref
    # Getting previous cache
    cached_data = cache.get(cache_key)

    # Checking if previously cached data exists
    if cached_data != None:
        # Returning cached data
        return cached_data
    else:
        image = "IMAGE NONE"

        # Getting temp image
        URL = "https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&key=" + settings.KEY
        URL += "&photoreference=" + photo_ref
        result = urllib.request.urlretrieve(URL)
        img_temp = NamedTemporaryFile(delete = True)
        img_temp.write(urlopen(URL).read())
        img_temp.flush()

        # Saving new data to cache
        cache.set(cache_key, File(img_temp), django_settings.CACHES["default"]["TIMEOUT"])
        return img_temp

Но этокод выбрасывает меня:

TypeError at /api/image_gallery/ChIJvxOujlf6PEcRIG3Mt57gV4A
cannot serialize '_io.BufferedRandom' object

Полный возврат:

Internal Server Error: /api/image_gallery/ChIJvxOujlf6PEcRIG3Mt57gV4A
Traceback (most recent call last):
  File "/home/dolidod/.local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/home/dolidod/.local/lib/python3.7/site-packages/django/core/handlers/base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/dolidod/.local/lib/python3.7/site-packages/django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/dolidod/.local/lib/python3.7/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/home/dolidod/.local/lib/python3.7/site-packages/django/views/generic/base.py", line 71, in view
    return self.dispatch(request, *args, **kwargs)
  File "/home/dolidod/.local/lib/python3.7/site-packages/rest_framework/views.py", line 495, in dispatch
    response = self.handle_exception(exc)
  File "/home/dolidod/.local/lib/python3.7/site-packages/rest_framework/views.py", line 455, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/home/dolidod/.local/lib/python3.7/site-packages/rest_framework/views.py", line 492, in dispatch
    response = handler(request, *args, **kwargs)
  File "/home/dolidod/coding/fest-apka/app/views.py", line 59, in get
    print(places_info.get_place_images_gallery(places_info, place_id))
  File "/home/dolidod/coding/fest-apka/app/scripts_for_api_control/high_level_code.py", line 135, in get_place_images_gallery
    cache.set(cache_key, File(img_temp), django_settings.CACHES["default"]["TIMEOUT"])
  File "/home/dolidod/.local/lib/python3.7/site-packages/django/core/cache/backends/filebased.py", line 54, in set
    self._write_content(f, timeout, value)
  File "/home/dolidod/.local/lib/python3.7/site-packages/django/core/cache/backends/filebased.py", line 44, in _write_content
    file.write(zlib.compress(pickle.dumps(value, self.pickle_protocol)))
  File "/usr/lib/python3.7/tempfile.py", line 620, in func_wrapper
    return func(*args, **kwargs)
TypeError: cannot serialize '_io.BufferedRandom' object
[03/Jul/2019 19:26:44] "GET /api/image_gallery/ChIJvxOujlf6PEcRIG3Mt57gV4A HTTP/1.1" 500 123133

Я думаю, что эта строка является проблемой: cache.set(cache_key, File(img_temp), django_settings.CACHES["default"]["TIMEOUT"])

Я думаю, что Джанго не знает, какиметь дело с изображениями.

Должен ли я каким-то образом конвертировать это изображение?Если я преобразую его, как я могу повторно получить это изображение (чтобы показать в моих шаблонах / отправить в мою среду интерфейса).

Или, может быть, я должен создать свою собственную модель, которая будет отвечать за кеширование (например, с полями Fields 'updated_at', 'image', 'api_reference')?

1 Ответ

0 голосов
/ 04 июля 2019

Я не уверен, почему вы делаете все это с помощью NamedTeilitaryFile, и еще меньше, почему вы затем оборачиваете это в объект File, прежде чем передать его в кэш. Особенно , поскольку urlretrieve уже уже сохранил объект как временный файл на диск; по какой-то причине вы извлекаете его на диск, затем берете URL-адрес и извлекаете его снова , оборачивая его во временный файл, а затем оборачивая этот временный файл в другой объект File. Не удивительно, что это не работает.

Вы можете прочитать файл, который urlretrieve сохранил, и передать его, но это будет бессмысленно. На самом деле вы должны вместо этого использовать urlopen и передать результат чтения прямо в кеш. Так что это просто:

result = urllib.request.urlopen(URL).read()
cache.set(cache_key, result)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...