How to get filename of file uploaded to imagefield? - django

I need to past in template a filename of file which uploaded in instance imagefield.
My class:
def conference_directory_path(instance, filename):
return 'dialogues/conferences/conference_{0}/avatar/{1}'.format(instance.id, filename)
class Dialogue(models.Model):
...
avatar = models.ImageField(upload_to=conference_directory_path, blank=True)
...
Template:
<img src="/static/dialogues/conferences/conference_{{ dialogue.id }}/avatar/{{ dialogue.avatar.filename }}" alt="">
But dialogue.avatar.filename is empty string after rendering. What's wrong? dialogue is an instance of Dialogue model.

What is stored in the database is in fact the filename and not the data. How to access it is described here:
https://docs.djangoproject.com/en/1.10/ref/models/fields/#filefield
All that will be stored in your database is a path to the file
(relative to MEDIA_ROOT). You’ll most likely want to use the
convenience url attribute provided by Django. For example, if your
ImageField is called mug_shot, you can get the absolute path to your
image in a template with {{ object.mug_shot.url }}.
so we have
<img src="{{ dialogue.avatar.url }}" alt="">

Related

How to sent images through django sendmail

I'm trying to send images in a letter, but it doesn’t work out for me. I tuned {{ STATIC_URL }} but it did not help... How i can fix this?
In settings: STATIC_URL = 'http://10.0.50.42:8103/static/'
In HTML: <img src="{{ STATIC_URL }}dc/images/banner2.png">
With this setting, I started to receive a letter, but the images are not displayed there.
First of all you have to load static files using below command as first line of html...
{% load static %}
then use static as below in your <img>...
<img src="{% static "dc/images/banner2.png" %}">
In my knowledge you cannot just put the link of image in the template that is rendered in the email and expect that it will work. As you are sending the image it still resides on your machine/server. The image must be saved as in, in a model and then you can you use that Model object to send as attachment.
Lets assume the file model is just below:
class ImageFile(models.Model):
file = models.ImageField(upload_to='Images',verbose_name='File Path', max_length=400, null=True)
and the send_mail function looks like:
def send_mail():
file_obj = ImageFile.objects.get(file='banner2.png')
file_url = file_obj.file.path
msg = EmailMessage(subject=subject, body=email_body, from_email=[frommail],
to=[tomail], bcc=[bcc mails])
msg.attach_file(file_url)
msg.send()

Default image not saving in DB

I have a requirement where if a user doesn't upload the image, the default image should be saved in DB for this I am using the default attribute in FileField but default image is not saving in DB.
file = models.FileField(upload_to='photos/',default='NoImage.jpg')
You can do like this. Give the full path prepending MEDIA_ROOT like
file = models.FileField(upload_to='photos/',default='settings.MEDIA_ROOT/photos/NoImage.jpg')
But I would suggest keep it null because in a case if lots of your user are not uploading any image. You are unnecessarily inserting those number of repetitive default image in database.
In you django-template you can handle
{% if not file %}
<img src= "{{ MEDIA_URL }}photos/NoImage.jpg">
{% endif %}
I think you should leave the field blank if no image is uploaded. It would make easier for auditing and filtering. I would just throw a property:
#property
def image_url(self):
if self.image:
return self.file.url
else:
return "default/image/path/default.jpg"

django cutom image name on upload

I need create a image upload with django, the problem is, django always saving in a global project(called linkdump) folder, I want save it on the project folder(linktracker).
setting.py:
STATIC_URL = '/static/'
model:
class Link(models.Model):
link_description = models.CharField(max_length=200)
link_url = models.CharField(max_length=200)
link_image = models.ImageField(upload_to= './static/')
def __str__(self):
return self.link_description
class Admin:
pass
now in the view:
<img src="{% static link.link_image %}" alt="{{ link.link_description }}">
it returns
http://127.0.0.1:8000/static/static/o-BLUE-LIGHT-SLEEP-facebook.jpg
and the upload is in the project folder(linkdump), not inside the app.
You can specify a function to return a custom path for the ImageField:
def get_upload_path(instance, filename):
return 'your/custom/path/here'
class Link(models.Model):
. . .
link_image = models.ImageField(upload_to=get_upload_path)
Now you can use information from the model instance to build up the path to upload to.
Additionally, you don't want to use the {% static %} template tag to specify the path to the image. You would just use the .url property of the field:
<img src="{{ link.link_image.url }}" alt="{{ link.link_description }}" />

ImageField: save filename only

I have model with ImageFile field:
def upload_course_cover(object, filename):
return '/media/courses/%s_%s' % (Course.objects.aggregate(Max('id'))['id__max'] + 1, filename)
class Course(models.Model):
# ...
cover = models.ImageField(upload_to=upload_course_cover, blank=True)
When the image is saved, into cover field will be writen full image path /media/courses/id_filename.ext, but I want store only image name id_filename.ext.
How to do it?
You cannot change what it stores in the database - unless you create your own custom field; or use a CharField.
If you just want to display the filename:
import os
c = Course.objects.get(pk=1)
fname = os.path.basename(c.cover.name)
# if cover's name is /hello/foo/bar.html
# fname will be bar.html
However, since you have image field - you can get lots of benefits out of it, for example - to get the URL to display the image in an img tag:
<img src="{{ c.cover.url }}"
alt="cover image for {{ c.name }}"
/>
You can also get some other benefits, for example:
class Course(models.Model):
# ....
cover_height = models.IntegerField()
cover_width = models.IntegerField()
cover = models.ImageField(upload_to=upload_course_cover,
height_field=cover_height,
width_field=cover_width,
# your other options...
)
Now you can do:
<img src="{{ c.cover.url }}" height="{{ c.cover_height }}" width="{{ c.cover_width }}">
"When the image is saved, into cover field will be writen full image path /media/courses/id_filename.ext"
To be precise, this is not true. Only the relative path from your MEDIA_ROOT is saved in the database. See https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.FileField.upload_to
(ImageField has the same properties as FileField)
To save only the filenames, you could
Add a new CharField to store the names
Use os.split() to get just the filename when called

How to display a couchdb image attachment in a Django template

I am using couchdb-python with Django. I am looking for a way to display an image (which is stored in the database as an attachment to a document) in a template. Oddly, I cannot find any example online of how to do this.
Currently, in the views.py I have something like this:
def displaypage(request,id):
docs = SERVER['docs']
try:
doc = docs[id]
except ResourceNotFound:
raise Http404
...
attachments = doc['_attachments']['someimage.jpg']
...
text_marked_down = markdown.markdown(doc['text'])
return render_to_response('couch_docs/display.html',{'row':doc,'attachments':attachments,'doctext':text_marked_down,...},context_instance=RequestContext(request))
Then, in the template display.html:
{% extends 'site_base.html' %}
{% block wrapper %}
{{ attachments }}
<div>{{ doctext|safe }}</div>
{{ endblock }}
I am seeing the text just fine, but for the image I only see the following:
{u'stub':True, u'length':27018,u'revpos':19,u'content_type': u'image/jpeg'}
So, clearly I am not passing the actual image, or not displaying it correctly anyway. Oddly, I cannot find an example online anywhere of how to actually do this. Can anyone point me to one, or provide it here?
You are using the template engine to render an HTML document. That document will be interpreted by the web browser just like any other HTML document.
Think about how an HTML page contains an image. The image is never inline within the HTML document itself. The HTML page contains a reference to instruct the browser to separately load the image and display it in place.
<img src="/path/to/image" />
So, likewise, you will need to:
create a separate view that will only return the binary data of the image. Set the mime type appropriately. See http://effbot.org/zone/django-pil.htm for some ideas how to return an image, but in your case set the contents of the response to be your image content.
add an <img ...> tag to your template that calls the new view you created.
once you drill down your db, you might want to consider building the url of each documents attachment as follows:
def function():
couch = couchdb.Server() #connect to server
db = couch['img'] #connect to database which contains docs with img attachments
doc_id = [] #create list of id's
http_docid = [] #create list to populate href for picture path
for i in db: #for each id in the db
doc_id.append(i) #add to the carid list
doc = db[i] #get the document id
for key in (doc['_attachments']): #for the key in the doc '_attacments' payload
print key #just to confirm
href_docid.append(('http://yourdbDomain/dbname/'+i+'/'+key)) #create a uri and append to a list
return href_docid
And below im using Jinja2's templating:
{% for img in function() %}
<img class="some-class" src="{{ img }}">
{% endfor %}
Hope this proves usefull!