I\'m new to Django (and Python) and I have been trying to work out a few things myself, before jumping into using other people\'s apps. I\'m having trouble understanding whe
Overriding the save method is a good option, but I'd be more tempted to use a signal in this case. Django signals allow you to "listen" to a given model type's various events; in this case, you'd be interested in the post_save
event.
I usually subscribe to such signals in my models.py
file. Code for you would look something like this:
from django.db.models.signals import post_save
from models import Country
def resize_image(sender, **kwargs):
country = kwargs["instance"]
resize_image(country.flag) # where resize_image generates a thumbnail given a Country instance
post_save.connect(resize_image, sender=Country)
Ryan is correct signals are a better way to go however the advantage of the overriden save is that we can get the old and new image paths, see if the image has changed (and if it has create a new thumbnail), save the model instance and then delete the old image and thumbnail.
Remember django does not clean up the old images for you so unless you have script to check that the images/thumbnails are still in use and clean out any that are not you will leak disk space. (This may or may-not be a problem for you depending on image size and frequency of updates)
I'm not sure how you could do this with a post_save signal, and I don't know enough about signals (That's research for tonight!) to know if there is a suitable pre_save signal. If i find one then I'll re-write the code above to use signals as a generic pre save listner.
A very easy way is to resize and/or crop your image on display with django-imagefit.
It will preserve the original image so you can have multiple versions, refactor your frontend later and it also works with non-model images.
If it's OK for you, there is a Django application ready, doing exactly what you want: https://github.com/sorl/sorl-thumbnail
A key question is: when should the thumbnail be generated?
If (1) I suggest you create a view that maps to url /flagthumbnail/countryid
. The view method would then have to:
Whenever you need to display a thumbnail flag, just use <a href="/flagthumbnail/countryid">
.
If (2), you could connect to Django's django.db.models.signals.post_save
signal and in the signal handler create and save a thumbnail file.
you can change photo size after save the data using 'Pillow' , for example i am going to change the user profile image to 300 x 300 :
1-first make sure 'Pillow' is installed .
2- here is my code :
from PIL import Image
class Profile(models.Model):
user_group_rule_options = [
('site_manager', 'site_manager'),
('site_sales', 'site_sales'),
('site_technical_support', 'site_technical_support'),
('site_user', 'site_user'),
]
PRF_user = models.OneToOneField(User, on_delete=models.CASCADE)
PRF_user_group = models.CharField(max_length=30, choices=user_group_rule_options, default='site_user')
PRF_image = models.ImageField(upload_to='profile_img', blank=True, null=True)
PRF_country = CountryField()
PRF_address = models.CharField(max_length=100)
PRF_join_date = models.DateTimeField(auto_now_add=True)
PRF_slug = models.SlugField(blank=True, null=True)
def save(self , *args , **kwargs):
# change profile image size
img = Image.open(self.PRF_image.path)
if img.width > 300 or img.height > 300:
output_size = (300, 300)
img.thumbnail(output_size)
img.save(self.PRF_image.path)