Django + Heroku + S3: boto -> локальная переменная "region_name", на которую ссылается перед присваиванием

Я получаю очень странную ошибку, из-за которой я действительно застрял на многие часы.

Я впервые выполнил развертывание с Heroku и использую S3 для файлов мультимедиа. Первое, что я заметил, было то, что у меня никогда не было успешной миграции после установки boto и django-storages-redux, не знаю почему. Во всяком случае, я продолжал идти.

Кажется, мои конфигурации работали в AWS, так как мои статические файлы вошли в мое ведро в первый раз, когда я попробовал это сделать, но я получил некоторые img-файлы, не поступающие, поэтому я решил переустановить boto и django-registration-redux (чтобы посмотреть, это будет мигрировать правильно).

В конце концов, он никогда не переносился, как ожидалось, и теперь я получаю следующую ошибку:

UnboundLocalError: local variable 'region_name' referenced before assignmentв моем пакете БОТО, когда коллекторный.

Я не понимаю, почему миграция не работает и почему я начал получать эту ошибку, когда переустанавливал boto и django-storages-redux.

Терминал:

You have requested to collect static files at the destination
location as specified in your settings.

This will overwrite existing files!
Are you sure you want to do this?

Type 'yes' to continue, or 'no' to cancel: yes
Traceback (most recent call last):
  File "/Users/Alex/Desktop/Allugare/src/manage.py", line 22, in <module>
    execute_from_command_line(sys.argv)
  File "/Users/Alex/Desktop/allugare/lib/python3.5/site-packages/django/core/management/__init__.py", line 367, in execute_from_command_line
    utility.execute()
  File "/Users/Alex/Desktop/allugare/lib/python3.5/site-packages/django/core/management/__init__.py", line 359, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Users/Alex/Desktop/allugare/lib/python3.5/site-packages/django/core/management/base.py", line 294, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/Users/Alex/Desktop/allugare/lib/python3.5/site-packages/django/core/management/base.py", line 345, in execute
    output = self.handle(*args, **options)
  File "/Users/Alex/Desktop/allugare/lib/python3.5/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 193, in handle
    collected = self.collect()
  File "/Users/Alex/Desktop/allugare/lib/python3.5/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 124, in collect
    handler(path, prefixed_path, storage)
  File "/Users/Alex/Desktop/allugare/lib/python3.5/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 349, in copy_file
    if not self.delete_file(path, prefixed_path, source_storage):
  File "/Users/Alex/Desktop/allugare/lib/python3.5/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 255, in delete_file
    if self.storage.exists(prefixed_path):
  File "/Users/Alex/Desktop/allugare/lib/python3.5/site-packages/storages/backends/s3boto.py", line 439, in exists
    if self.entries:
  File "/Users/Alex/Desktop/allugare/lib/python3.5/site-packages/storages/backends/s3boto.py", line 302, in entries
    for entry in self.bucket.list(prefix=self.location))
  File "/Users/Alex/Desktop/allugare/lib/python3.5/site-packages/storages/backends/s3boto.py", line 301, in <genexpr>
    self._entries = dict((self._decode_name(entry.key), entry)
  File "/Users/Alex/Desktop/allugare/lib/python3.5/site-packages/boto/s3/bucketlistresultset.py", line 34, in bucket_lister
    encoding_type=encoding_type)
  File "/Users/Alex/Desktop/allugare/lib/python3.5/site-packages/boto/s3/bucket.py", line 473, in get_all_keys
    '', headers, **params)
  File "/Users/Alex/Desktop/allugare/lib/python3.5/site-packages/boto/s3/bucket.py", line 399, in _get_all
    query_args=query_args)
  File "/Users/Alex/Desktop/allugare/lib/python3.5/site-packages/boto/s3/connection.py", line 668, in make_request
    retry_handler=retry_handler
  File "/Users/Alex/Desktop/allugare/lib/python3.5/site-packages/boto/connection.py", line 1071, in make_request
    retry_handler=retry_handler)
  File "/Users/Alex/Desktop/allugare/lib/python3.5/site-packages/boto/connection.py", line 927, in _mexe
    request.authorize(connection=self)
  File "/Users/Alex/Desktop/allugare/lib/python3.5/site-packages/boto/connection.py", line 377, in authorize
    connection._auth_handler.add_auth(self, **kwargs)
  File "/Users/Alex/Desktop/allugare/lib/python3.5/site-packages/boto/auth.py", line 755, in add_auth
    **kwargs)
  File "/Users/Alex/Desktop/allugare/lib/python3.5/site-packages/boto/auth.py", line 574, in add_auth
    string_to_sign = self.string_to_sign(req, canonical_request)
  File "/Users/Alex/Desktop/allugare/lib/python3.5/site-packages/boto/auth.py", line 514, in string_to_sign
    sts.append(self.credential_scope(http_request))
  File "/Users/Alex/Desktop/allugare/lib/python3.5/site-packages/boto/auth.py", line 496, in credential_scope
    region_name = self.determine_region_name(http_request.host)
  File "/Users/Alex/Desktop/allugare/lib/python3.5/site-packages/boto/auth.py", line 690, in determine_region_name
    return region_name
UnboundLocalError: local variable 'region_name' referenced before assignment

settings.py:

   ... 
   INSTALLED_APPS = (
        #DJANGO APPS
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.sites',
        'django.contrib.messages',
        'django.contrib.staticfiles',

        #THIRD PARTY APPS
        'allauth',
        'allauth.account',
        'allauth.socialaccount',

        #Social Authentications
        'allauth.socialaccount.providers.facebook',
        # 'allauth.socialaccount.providers.instagram',
        # 'allauth.socialaccount.providers.twitter',

        'crispy_forms',
        'django_messages',
        'storages',

        #MY APPS
        'lares',
        'mensagens',
        'profiles',
    )

    ...
    STATIC_URL = '/static/'
    STATIC_ROOT = os.path.join(BASE_DIR, "static-live", "static")


    MEDIA_URL = '/media/'
    MEDIA_ROOT = os.path.join(BASE_DIR, "static-live", "media")

    STATICFILES_DIRS = (
        os.path.join(BASE_DIR, "static"),
        )

    AWS_ACCESS_KEY_ID = "***"
    AWS_SECRET_ACCESS_KEY = "***"


    AWS_FILE_EXPIRE = 200
    AWS_PRELOAD_METADATA = True
    AWS_QUERYSTRING_AUTH = True

    DEFAULT_FILE_STORAGE = 'allugare.utils.MediaRootS3BotoStorage'
    STATICFILES_STORAGE = 'allugare.utils.StaticRootS3BotoStorage'
    # DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
    # STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
    AWS_STORAGE_BUCKET_NAME = 's3allugare'
    S3DIRECT_REGION = 'sa-east-1'
    S3_URL = '//%s.s3.amazonaws.com/' % AWS_STORAGE_BUCKET_NAME
    MEDIA_URL = '//%s.s3.amazonaws.com/media/' % AWS_STORAGE_BUCKET_NAME
    MEDIA_ROOT = MEDIA_URL
    STATIC_URL = S3_URL + 'static/'
    ADMIN_MEDIA_PREFIX = STATIC_URL + 'admin/'
    AWS_S3_HOST = 'sa-east-1.amazonaws.com'

    import datetime

    two_months = datetime.timedelta(days=61)
    date_two_months_later = datetime.date.today() + two_months
    expires = date_two_months_later.strftime("%A, %d %B %Y 20:00:00 GMT")

    AWS_HEADERS = {
        'Expires': expires,
        'Cache-Control': 'max-age=%d' % (int(two_months.total_seconds()), ),
    }

wsgi.py

"""
WSGI config for allugare project.

It exposes the WSGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/1.10/howto/deployment/wsgi/
"""

import os
from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "allugare.settings")

application = get_wsgi_application()

utils.py

from storages.backends.s3boto import S3BotoStorage

StaticRootS3BotoStorage = lambda: S3BotoStorage(location='static') # S3 bucket name -> static
MediaRootS3BotoStorage  = lambda: S3BotoStorage(location='media')  # S3 bucket name -> static

1 ответ

Решение

Хорошо, вот в чем дело, если вы не используете регион AWS по умолчанию, вы должны быть осторожны при обновлении своего региона, поскольку S3 имеет разные форматы в зависимости от региона.

Я в Южной Америке, поэтому я использую sa-east-1 (для Сан-Паулу).

Для меня это сработало, когда я изменил настройку: AWS_S3_HOST = 'sa-east-1.amazonaws.com' на AWS_S3_HOST = 's3-sa-east-1.amazonaws.com'

Наслаждайтесь!

Другие вопросы по тегам