Изменение URL-адреса поля ImageField
Я пытаюсь исправить URL-адреса изображений, вызывая метод correct_image_url модели Page. Однако по какой-то причине результат не сохраняется. Таким образом, хотя все работает правильно, на шаге, где я выполняю:
print(f"New URL of the page: {new_image_url}")
возвращается старый URL.
class Page(models.Model):
image = models.ImageField(
max_length=400,
storage=S3Boto3Storage(),
validators=[FileSizeValidator(limit_value=8)])
number = models.PositiveIntegerField(default=0, blank=True, null=True)
chapter = models.ForeignKey(Chapter, on_delete=models.CASCADE)
objects = PageManager()
def correct_image_url(self):
url = self.image.url
corrected_url = url.replace(
"https%3A/dist.cloudfront.net", "https://dist.cloudfront.net")
domain = "https://dist.cloudfront.net"
first_occurrence = corrected_url.find(domain)
second_occurrence = corrected_url.find(
domain, first_occurrence + len(domain))
if second_occurrence != -1:
corrected_url = corrected_url[:second_occurrence]
if corrected_url != url:
if self.image:
original_url = self.image.url
print(
f"Correcting URL from: {original_url} to {corrected_url}")
self.image = corrected_url
try:
self.save()
self.refresh_from_db()
new_image_url = self.image.url
print(f"New URL of the page: {new_image_url}")
except DataError:
print(
f"Skipped saving due to DataError for URL: {corrected_url}")
except ValidationError as e:
print(
f"Validation error: {e.messages} for URL: {corrected_url}")
Я запускаю его в оболочке Django следующим образом:
from app.models import Page
for page in Page.objects.all()[:1]:
page.correct_image_url()
Также, когда я пытаюсь запустить
self.image.url = corrected_url
Возвращается
AttributeError: cannot set attribute
Вы делаете что-то необычное. Доменное имя в URL-адресе изображения должно браться из MEDIA_URL. Оно никогда не должно храниться в пути ImageField. image.url
состоит из MEDIA_URL + относительный путь к изображению. Для изменения MEDIA_URL необходимо определить что-то вроде переменной окружения.
ImageField.url - это функция, унаследованная от класса FileField. Она не может быть обновлена, ее значение не хранится в БД. Оно вычисляется на лету.
Если вы храните доменное имя и протокол в атрибутах ImageField - вы нарушаете концепции Django, функциональность используется не по назначению.