Настройка Django и Google Cloud Storage?
Я не, используя Appengine.
У меня есть обычное приложение Django с ванилью, работающее на виртуальной машине. Я хочу использовать Google Cloud Storage для обслуживания своих статических файлов, а также для загрузки/обслуживания моих медиафайлов.
У меня есть ведро.
Как связать приложение Django с моим ведром? Я пробовал django-storages
. Это может сработать, но что мне нужно сделать, чтобы подготовить мое ведро для использования моим приложением django? И какая базовая конфигурация мне нужна в настройках Django?
Текущие настройки:
# Google Cloud Storage
# http://django-storages.readthedocs.org/en/latest/backends/apache_libcloud.html
LIBCLOUD_PROVIDERS = {
'google': {
'type' : 'libcloud.storage.types.Provider.GOOGLE_STORAGE',
'user' : <I have no idea>,
'key' : <ditto above>,
'bucket': <my bucket name>,
}
}
DEFAULT_LIBCLOUD_PROVIDER = 'google'
DEFAULT_FILE_STORAGE = 'storages.backends.apache_libcloud.LibCloudStorage'
STATICFILES_STORAGE = 'storages.backends.apache_libcloud.LibCloudStorage'
Ответы
Ответ 1
Django-хранилища имеют бэкэнд для облачного хранилища Google, но он не документирован, я понял, что смотрю в репо. Он работал с этой настройкой:
DEFAULT_FILE_STORAGE = 'storages.backends.gs.GSBotoStorage'
GS_ACCESS_KEY_ID = 'YourID'
GS_SECRET_ACCESS_KEY = 'YourKEY'
GS_BUCKET_NAME = 'YourBucket'
STATICFILES_STORAGE = 'storages.backends.gs.GSBotoStorage'
Чтобы получить YourKEY и YourID, вы должны создать клавиши Interoperability
на вкладке настроек.
Надеюсь, что это поможет, и вам не нужно учиться этому трудно:)
А в случае, если вы еще этого не сделали, зависимости:
pip install django-storages
pip install boto
Ответ 2
Джанго-хранилища, по сути, жизнеспособная альтернатива. Вы должны быть осторожны с бэкэндом Google Cloud, хотя метод url()
который он предоставляет, вызывает ненужные HTTP-вызовы в Google. (Django вызывает .url() при рендеринге статических файлов, например).
https://github.com/jschneier/django-storages/issues/491
settings.py
DEFAULT_FILE_STORAGE = 'config.storage_backends.GoogleCloudMediaStorage'
STATICFILES_STORAGE = 'config.storage_backends.GoogleCloudStaticStorage'
GS_PROJECT_ID = '<google-cloud-project-id>'
GS_MEDIA_BUCKET_NAME = '<name-of-static-bucket>'
GS_STATIC_BUCKET_NAME = '<name-of-static-bucket>'
STATIC_URL = 'https://storage.googleapis.com/{}/'.format(GS_STATIC_BUCKET_NAME)
MEDIA_URL = 'https://storage.googleapis.com/{}/'.format(GS_MEDIA_BUCKET_NAME)
storage_backends.py
"""
GoogleCloudStorage extensions suitable for handing Django's
Static and Media files.
Requires following settings:
MEDIA_URL, GS_MEDIA_BUCKET_NAME
STATIC_URL, GS_STATIC_BUCKET_NAME
In addition to
https://django-storages.readthedocs.io/en/latest/backends/gcloud.html
"""
from django.conf import settings
from storages.backends.gcloud import GoogleCloudStorage
from storages.utils import setting
from urllib.parse import urljoin
class GoogleCloudMediaStorage(GoogleCloudStorage):
"""GoogleCloudStorage suitable for Django Media files."""
def __init__(self, *args, **kwargs):
if not settings.MEDIA_URL:
raise Exception('MEDIA_URL has not been configured')
kwargs['bucket_name'] = setting('GS_MEDIA_BUCKET_NAME', strict=True)
super(GoogleCloudMediaStorage, self).__init__(*args, **kwargs)
def url(self, name):
""".url that doesn't call Google."""
return urljoin(settings.MEDIA_URL, name)
class GoogleCloudStaticStorage(GoogleCloudStorage):
"""GoogleCloudStorage suitable for Django Static files"""
def __init__(self, *args, **kwargs):
if not settings.STATIC_URL:
raise Exception('STATIC_URL has not been configured')
kwargs['bucket_name'] = setting('GS_STATIC_BUCKET_NAME', strict=True)
super(GoogleCloudStaticStorage, self).__init__(*args, **kwargs)
def url(self, name):
""".url that doesn't call Google."""
return urljoin(settings.STATIC_URL, name)
Примечание. Проверка подлинности по умолчанию выполняется с помощью переменной среды GOOGLE_APPLICATION_CREDENTIALS.
https://cloud.google.com/docs/authentication/production#setting_the_environment_variable
Ответ 3
Итак, это в основном будет работать. (С помощью этой библиотеки и настроек).
Трюк, чтобы заставить его работать, знает, где получить параметры 'user'
и 'key'
для libcloud.
В Google Cloud Console > Storage
нажмите Settings
. Затем нажмите правую вкладку под названием Interoperability
. На этой панели есть одиночная кнопка, которая говорит что-то вроде Enable Interoperability
. Нажмите на нее.
Voila! Теперь у вас есть имя пользователя и ключ.
Примечание. Не используйте django-storages
из pypi. Он не обновлялся и не работает с недавними выпусками Django.
Используйте эту версию:
pip install -e 'git+https://github.com/jschneier/django-storages.git#egg=django-storages'
Изменить: Если вы хотите использовать обратный прокси, вы можете рассмотреть мою слегка измененную версию.
https://github.com/jschneier/django-storages/compare/master...halfnibble:master
Описание:
При определенных обстоятельствах может потребоваться загрузка файлов с использованием обратного прокси. Это может быть использовано для облегчения ошибок запроса перекрестного происхождения.
Этот небольшой PR позволяет разработчику установить опцию LIBCLOUD_PROXY_URL в settings.py.
Пример использования
# Apache VirtualHost conf
ProxyPass /foo http://storage.googleapis.com
ProxyPassReverse /foo http://storage.googleapis.com
# settings.py
LIBCLOUD_PROXY_URL = '/foo/'
Ответ 4
Так как я не могу комментировать ответ Алана Вагнера, вот дополнение.
Если вы используете python3, вы можете получить эту ошибку,
...
ImportError: No module named 'google_compute_engine'
Если это так, вам нужно будет установить google-compute-engine. Файл /etc/boto.cfg
сообщает python использовать версию библиотеки 2.7. Вам нужно будет запустить следующую строку для регенерации /etc/boto.cfg
.
python3 -c "from google_compute_engine.boto.boto_config import BotoConfig; BotoConfig()"
Еще одна ошибка, которую вы можете поразить,
...
File "/app/venv/lib/python3.4/site-packages/boto/gs/connection.py", line 95, in create_bucket
data=get_utf8_value(data))
File "/app/venv/lib/python3.4/site-packages/boto/s3/connection.py", line 656, in make_request
auth_path = self.calling_format.build_auth_path(bucket, key)
File "/app/venv/lib/python3.4/site-packages/boto/s3/connection.py", line 94, in build_auth_path
path = '/' + bucket
TypeError: Can't convert 'bytes' object to str implicitly
Я сделал запрос pull, чтобы исправить это. Вы можете использовать мое репо в качестве зависимости от пипса, если хотите, пока он не будет слит.
Я постараюсь сохранить это репо в актуальном состоянии. Я установил ветвь develop
по умолчанию как защищенную. Я единственный, кто может совершать/одобрять запросы на слияние. Я также сделал только один коммит.
Вам нужно будет установить google-compute-engine и запустить эту строку выше, прежде чем вы сможете установить/создать мое репозитование boto.
Ответ 5
В последней версии ключ доступа и идентификатор ключа изменены на файл учетной записи службы. И мы хотим использовать корзину с 2 static
папками и media
как локальный сервер. Ниже приведены конфиги обновления:
Создайте файл, подобный gcloud_storages.py
:
"""
Modify django-storages for GCloud to set static, media folder in a bucket
"""
from django.conf import settings
from storages.backends.gcloud import GoogleCloudStorage
class GoogleCloudMediaStorage(GoogleCloudStorage):
"""
GoogleCloudStorage suitable for Django Media files.
"""
def __init__(self, *args, **kwargs):
kwargs['location'] = 'media'
super(GoogleCloudMediaStorage, self).__init__(*args, **kwargs)
class GoogleCloudStaticStorage(GoogleCloudStorage):
"""
GoogleCloudStorage suitable for Django Static files
"""
def __init__(self, *args, **kwargs):
kwargs['location'] = 'static'
super(GoogleCloudStaticStorage, self).__init__(*args, **kwargs)
Используйте аргумент location
для установки местоположения статических медиа файлов в корзине.
В settings.py
from google.oauth2 import service_account
...
GOOGLE_APPLICATION_CREDENTIALS = '/path/service-account.json'
DEFAULT_FILE_STORAGE = 'app.gcloud_storages.GoogleCloudMediaStorage'
STATICFILES_STORAGE = 'app.gcloud_storages.GoogleCloudStaticStorage'
GS_BUCKET_NAME = 'name-of-bucket'
GS_PROJECT_ID = 'project-id'
GS_DEFAULT_ACL = 'publicRead'
GS_CREDENTIALS = service_account.Credentials.from_service_account_file(
GOOGLE_APPLICATION_CREDENTIALS
)