Изображения загружаются в S3, но URL в приложении django отображается некорректно
Проблема
Я могу загружать изображения в S3, однако структура URL в моем приложении django не структурирована должным образом.
URL выглядит следующим образом: http://localhost:8000/plants/https://'%s.s3.amazonaws.com'%AWS_STORAGE_BUCKET_NAME/media/plant_images/image.jpeg
Однако я хочу, чтобы он отображался как https://opensprouts-dev-media.s3.amazonaws.com/media/plant_images/images.jpeg.
Контекст
У меня есть модель, которая позволяет мне загружать несколько изображений. Я думаю, что мне нужно переписать способ вызова изображения в моем шаблоне или в моей модели. Прочитав документацию Django и другие вопросы на stackoverflow, я не уверен, как решить эту проблему
settings.py/base.py
# MEDIA
# ------------------------------------------------------------------------------
USE_S3 = os.getenv('USE_S3') == 'TRUE'
AWS_ACCESS_KEY_ID = config('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = config('AWS_SECRET_ACCESS_KEY')
AWS_STORAGE_BUCKET_NAME = config('AWS_STORAGE_BUCKET_NAME')
AWS_QUERYSTRING_AUTH = config('AWS_QUERYSTRING_AUTH')
AWS_S3_CUSTOM_DOMAIN = config('AWS_S3_CUSTOM_DOMAIN')
AWS_S3_OBJECT_PARAMETERS = {
'CacheControl': 'max-age=86400',
}
AWS_LOCATION = config('AWS_LOCATION')
PUBLIC_MEDIA_LOCATION = 'media'
AWS_QUERYSTRING_AUTH = False
MEDIA_URL = 'https://%s/%s/' % (AWS_S3_CUSTOM_DOMAIN, AWS_LOCATIN)
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
Раздел моего шаблона, который вызывает URL {{ image.images.url }}
{% for image in plant.plant_images.all %}
{% if forloop.first %}
<div class="carousel-item active">
{% else %}
<div class="carousel-item">
{% endif %}
<img src="{{ image.images.url }}" alt="{{ plant.name }}">
</div>
{% endfor %}
</div>
models.py
import datetime
from django.conf import settings
from django.db import models
from django.utils import timezone
from django.template.defaultfilters import slugify
from django.urls import reverse
from django_quill.fields import QuillField
# Create your models here.
class Plant(models.Model):
name = models.CharField(max_length=120)
slug = models.SlugField(null=False, unique=True)
description = models.TextField()
def __str__(self):
return self.name
def publish(self):
self.published_date = timezone.now()
self.save()
def get_absolute_url(self):
return reverse("plant_detail", kwargs={"slug": self.slug})
class PlantImage(models.Model):
plant = models.ForeignKey(Plant, default=None, on_delete=models.CASCADE, related_name="plant_images")
images = models.ImageField(upload_to = 'plant_images/')
def __str__(self):
return self.plant.name
views.py
from .models import Plant, PlantImage
def plant_index(request):
plant_objects = Plant.objects.all()
context = {'plant_objects': plant_objects}
return render(request, 'plants/plant_index.html', context)
class PlantDetailView(DetailView):
model = Plant
template_name = 'plants/plant_detail.html'
slug = 'slug'
def get_context_data(self, **kwargs):
context = super(PlantDetailView, self).get_context_data(**kwargs)
context['plant_images'] = PlantImage.objects.all()
return context
plant_detail = PlantDetailView.as_view()
Я вижу, что изображения успешно сохраняются в s3 после того, как я загружаю их через мой внутренний пользовательский интерфейс Django, однако URL не позволяет мне правильно отображать изображения на странице.
Вы можете использовать boto3 config для загрузки изображений и это не добавит http://localhost:8000/plants
в базовый url изображения.
from storages.backends.s3boto import S3BotoStorage
class PublicMediaStorage(S3Boto3Storage):
location = "media"
default_acl = "public-read"
file_overwrite = False
custom_domain = False
и используйте вышеуказанный класс в вашей модели, используя параметры хранения модели django
class PlantImage(models.Model):
plant = models.ForeignKey(Plant, default=None, on_delete=models.CASCADE, related_name="plant_images")
images = models.ImageField(storage=PublicMediaStorage() ,upload_to = 'plant_images/')
def __str__(self):
return self.plant.name