I'm attempting to correct my image URLs by invoking the correct_image_url method of the Page model. However, for some reason, the result is not being saved. Thus, while it operates correctly, at the step where I execute:
print(f"New URL of the page: {new_image_url}")
it returns the old 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}")
I run it in the Django shell like this:
from app.models import Page
for page in Page.objects.all()[:1]:
page.correct_image_url()
Also, when i try to run
self.image.url = corrected_url
It returns
AttributeError: can't set attribute
You are doing something unusual. Domain name in the image URL should come from MEDIA_URL. It should never be stored in ImageField path. image.url
is composed from MEDIA_URL + image relative path. For changing MEDIA_URL you should define something like environment variable.
ImageField.url is a function inherited from FileField class. It cannot be updated, its' value is not stored in DB. It is computed on the fly.
If you store domain name and protocol in ImageField attributes - you're violating Django concepts, functionality is misused.