Djangothumbnails app issue - django

I an using this plugin to generate thumbnails. But somhow I couldn't make it work. The models work well, as images can be uploaded from the admin interface, even thumbnails get generated. I uploaded an image named "myphoto.jpg". The view I have is this.
def mainpage(request,slug):
page = get_object_or_404(MainPage, slug=slug)
image = get_object_or_404(Image)
return direct_to_template(request, 'flatpage.html',
extra_context={
'page':page,
'image':image,
})
I have defined the class in models as "Image". I had this in the template:
<img src="{% image.photo.myphoto_125x125 %}"> But the template shows error.
This is my model:
class Image(models.Model):
title = models.CharField(max_length=100)
photo = ImageWithThumbsField(upload_to='images/', sizes=((125,125),(200,200)))
# second_photo = ImageWithThumbsField(upload_to='site_media/images')
def __unicode__(self):
return self.title
The second field, "second_photo" I have commented out as it created duplicate copy of the main image. Even I am looking for a way to create entry for actual unsized image in the first field itself.

I havent tried this app, but I am using PIL to create thumbnail versions of uploaded images, and using a def in the model to retrieve the path to the thumbnail for display. This may be more of a manual approach than you are looking for but it works ok for me. You can override the save method on your model (which has your FileField) or send a post_save signal to a def to create the thumbnail.
But curious to know if this app you are using adds some useful functionality over this manual approach.

Somehow I got it working. Instead of creating a separate class, I used this line photo = ImageWithThumbsField(blank=True, upload_to='images/', sizes=((125,125),(200,200))) in my blog class. And I used the line {{% post.photo.url_125x124 %} in my index.html template.

Related

Django ImageField Creating New Folder by ID on upload?

I'm Currently developing a app with a ManyToMany ImageField Relantionship . I want to have the ImageField save all images to a specific folder based on the ID of the Relantionship.
I want to have something like this.
class PostImages(models.Model):
image = models.ImageField(upload_to='Post_Images/post/' + post.id)
class Post(models.Model):
images = models.ManyToManyField(PostImages)
How do I access the post.id to do this ? I mostly want to do this for organization purposes right now cause its on my local machine but also see no reason to change it when I deploy.
E.g. based on FileField^ but the same you can use for ImageField:
def get_file_path(instance, filename):
return instance.created.strftime("folder/%Y/%m/%d/") + instance.post.id
bfile = models.FileField(upload_to=get_file_path, null=True)

Django Admin show Image immediately after upload

maybe this issue is answered elsewhere, but I have no luck of finding it.
Here is my issue:
I have a Django admin site that has an ImageField to upload image look like this
In order to show the uploaded image, I will have to click on Save/ Save and add another/ Save and continue editing.
What I really want is show preview of the picture immediately after I upload it.
Is there anyway to trigger it via ImageField override or somehow?
Any suggestion would be appreciated
You can't do that because you haven't actually uploaded the image yet. When you "choose file" you've basically just told the browser which file you want to upload, but it doesn't get uploaded until you submit the form.
I am using sorl.thumbnail, but you can easily adapt it into django.
Below is Django model class
Class ImageModel(admin.Models):
...
myfield = models.ImageField(_("Image"), upload_to='project/%Y', null=True, blank=True)
...
#property
def image_tag(self):
im = get_thumbnail(self.myfield.file, 'x300', crop='center', quality=99)
return mark_safe('<img src="%s" width="%s" height="%s" />' % (im.url, im.width, im.height))

Is there a workaround for using Wagtail Image tags in views.py

I've the following problem:
In my models.py I'm using a Wagtail Image like this:
class ArtWork(models.Model):
image = models.ForeignKey(
'wagtailimages.Image',
on_delete=models.CASCADE,
related_name='+'
)
...
...
...
I know i can use the Image in my templates now like this:
{% image artwork.image height-100 %}
But for my current project I need to use the Image tag in my views.py because I'd like to generate a Pdf with it.
by simple using artwork.image just the Title of the Image returns but I'd need something like:
<img alt="SomeName" src="/media/images/SomeName_155x200.max-1200x1200_22b3pND.height-100.jpg" width="77" height="100">
Also artwork.image.url gives no result.
How can I use Wagtail Images outside my templates?
If you need to get an URL of rendition (thumbnail), you can do the following:
artwork_page_object.image.get_rendition('height-100').url
or to access rendition file:
artwork_page_object.image.get_rendition('height-100').file
Instead of height-100 you can use any valid resizing method for the image template tag (see the documentation for the image tag)
If you want to access original image you can do it like:
artwork_page_object.image.file
Useful docs:
Wagtail: More control over page rendering
Wagtail: Generating renditions in Python (Thanks, #shacker)
Django: ImageField and FileField
Template tags are just functions you can find the code on github. The image tag relies on the models Filter and Rendition.
I would recommend to read that code to understand how it works and afterwards use it in your view.
As noted by user Shacker here are the docs: https://docs.wagtail.org/en/stable/advanced_topics/images/renditions.html#image-renditions
Example:
# in your models
from wagtail.core.models import Page
class MyCustomPageModel(Page):
photo = models.ForeignKey(
'wagtailimages.Image',
...
# in your view
from myapp.models import MyCustomPageModel
p = MyCustomPageModel.objects.all()[0]
r = p.photo.get_rendition('fill-300x150')
print(r.url)

sorl-thumbnail ImageField dynamic upload_to path

I know theres a way to dynamic upload path in django ImageFields and FileFields, which is to pass a upload_to=callable in the field, but is there a way to achieve this with sorl-thumbnail ImageField?
This is my model.py, Im getting a upload_path not defined!
class Brand(models.Model):
title = models.CharField(max_length=255, null=True, blank=True)
photo = sorl.thumbnail.ImageField(upload_to=upload_path)
external = models.BooleanField(_('External Brand? ("Key Account")?'))
def upload_path(self):
return u'%s' % self.title
See this related SO question.
Sorl-thumbnail doesn't do anything special with upload_to. It merely punts the handling of passed arguments via inheriting from Django's FileField, so anything that works with a standard FileField or ImageField will work with sorl-thumbnail's ImageField as well.
I think your problem is defining the method on the model. Every implementation I've ever seen or done myself has the method being outside the model. Django automatically passes in the instance to the method, so that's how you access the data on the model -- not through self.
I use this callback with sorl:
def get_image_path(instance, filename):
"""
puts image in MEDIA_ROOT/photos/instance_id/file
"""
return os.path.join('photos', str(instance.id), filename)
class Brand(models.Model):
...
photo = sorl.thumbnail.ImageField(upload_to=get_image_path)

Provide a default profile picture if ever empty

I would like to provide a default profile picture for a user. I've used the default feature on the ImageField, but it acts more like an 'initial' than a default. I've read over the answers to this question: Default image for ImageField in Django's ORM, but I'd like to solve the problem at the model level and it does not address with FK relationships.
Here is what I currently have:
class Avatar(models.Model):
avatar = models.ImageField(upload_to=upload_to)
avatar_thumbnail = models.ImageField(upload_to=upload_to)
profile = models.ForeignKey(UserProfile)
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
...
I've tried adding the following function to the UserProfile model (and more than likely, incorrect code) --
# in UserProfile(models.Model)
def create_default_avatar(self):
if not self.avatar_set.all():
avatar = profile.avatar_set.create(profile=self.__class__)
avatar.avatar = File(open('media/default_profile_picture.jpg'))
avatar.avatar_thumbnail = File(open('media/default_profile_picture_thumbnail.jpg'))
avatar.save()
Could someone please show me how to create a true default picture for a profile. Thank you.
Ignacio's answer is simple but not perfect. It breaks the DRY principle. You have to add in all your templates the {% if image %} statements. I suggest creating a property on on the model, which will handle that for you (in all places at once).
class Avatar(models.Model):
(...)
#property
def avatar_image_url(self):
# Pseudocode:
if has image:
return url to the image
else:
return url to default image
Then in template you just do:
<img src="{{ item.avatar_image_url }}" alt="..."/>
Store nothing in the field if the default is to be used, and use the {% if %} template tag to detect this.