Default image not saving in DB - django

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"

Related

Django - How to return to default image after users delete their uploaded image?

So I originally had the user create a post in admin and be able to leave image field blank and Django would set a default image.
My problem is;
If a user uploads an image, then deletes the image in admin, I get an error: The 'image' attribute has no file associated with it. when accessing solo.html in browser.
How can I make the default image reappear and specifically come from static folder?
My code:
settings.py
STATIC_URL = '/static/'
STATIC_DIRS = os.path.join(BASE_DIR, 'static')
models.py
# FIXME: If default image is changed to user's upload but then deleted. Make default image reappear.
# Recipe Field
class Recipe(models.Model):
title = models.CharField(max_length=200)
image = models.ImageField(upload_to='recipes/images/', blank=True)
def get_image(self):
if not self.image:
return f'{settings.STATIC_URL}default.png'
return self.image.url
solo.html
<h2>{{ recipe.title }}</h2>
<h3>{{ recipe.category }}</h3>
<h3>{{ recipe.meal }}</h3>
<img src="{{ recipe.image.url }}">
I'm just starting with Django so I apologize in advance if it's all a mess.
Thank you in advance!
What's happening is that the file itself is being deleted, but recipe.image is not being set to None.

Django call CBV form other place

hey guys I have a specific issue.
I have a view:
class Upload(CreateView):
model = Banner
fields = ["image"]
success_url = '/url/'
def form_valid(self, form):
#some specifics operations...
This image are uploading to /upload
And in other place (e.g. /other_place, image in this dict are not uploading) I have a directory with other images. I get path to this images:
for file in glob.glob("*.jpg"):
l.append(file)
And in template:
{% for i in l %}
<img src="{{MEDIA_URL}}other_place/{i}}">
{%endfor%}
And I have nice template with all of this image. But now I need to upload selected image. specifically I need to call Upload view to upload selected image. Do you know what I mean? :D

How to retrieve absolute urls to thumbnails generated via django-filer easy-thumbnails

I am using following template tags to display thumbnails in my templates
{% load thumbnail %}
{% thumbnail obj.image 250x250 crop %}
thumbnail template tag returns relative urls to thumbnail image files as expected. But I would like it to return absolute urls. Normally easy-thumbnails has THUMBNAIL_MEDIA_URL = '' setting which allows thumbnail's storage to build absolute urls but it does not work with django-filer.
Is there any other way to achieve what I want?
You can extract the thumbnail properties using as
{% thumbnail obj.image 250x250 as thumb %}
{{thumb.url}}
See http://easy-thumbnails.readthedocs.org/en/latest/usage/#thumbnail-tag
EDIT:
If by "absolute" you mean including the website, I would recommend doing the logic elsewhere.
Considering image to be a FilerImageField, create a property in the models.py. Example:
from django.contrib.sites.models import Site
from easy_thumbnails.files import get_thumbnailer
#property
def thumbnail_absolute_url(self):
if self.image:
thumbnailer_options = {'size': (250, 250), 'crop': True}
thumb = get_thumbnailer(self.image).get_thumbnail(thumbnailer_options)
thumb_url = thumb.url
site = Site.objects.get_current()
return site.domain + thumb_url
return None
See https://github.com/SmileyChris/easy-thumbnails#manually-specifying-size--options

django-imagekit - better way of showing a default image?

I'm using django-imagekit to resize my user avatars and right now to display a default avatar (if the user didn't upload his/her avatar) I do this:
views.py
try:
usr_avatar = UsrAvatar.objects.get(user=request.user.id)
except UsrAvatar.DoesNotExist:
usr_avatar = UsrAvatar.objects.get(id='0')
template.html
<img src="{{ usr_avatar.avatar_image.url }}" >
This works fine but every time a user didn't upload his/her avatar I'm hitting the database for the default avatar image.
Is there a way to eliminate hitting the database when the user doesn't have an avatar image loaded by somehow attributing the default image link to usr_avatar or just doing something in the template.html? Thank you!
Apt username given your question!
You could create a context processor that provides the default avatar to every template and simply make sure that the context processor caches the image
settings.py
TEMPLATE_CONTEXT_PROCESSORS = (
...
'myapp.context_processors.default_avatar',
...
)
myapp/context_processors.py
from django.core.cache import cache
def default_avatar(request):
default_avatar = cache.get('default_avatar', False)
if not default_avatar:
default_avatar = UsrAvatar.object.get(id='0')
return {
'default_avatar' : default_avatar
}
Now the template variable 'default_avatar' is available in every template:
{% if usr_avatar %}
{{ usr_avatar }}
{% else %}
{{ default_avatar }}
{% endif %}
Alternatively just use the cache in your original query:
try:
usr_avatar = UsrAvatar.objects.get(user=request.user.id)
except UsrAvatar.DoesNotExist:
usr_avatar = cache.get('default_avatar', False)
if not usr_avatar:
usr_avatar = UsrAvatar.objects.get(id='0')
But Finally, it might be even better to avoid keeping the default avatar in the database at all and instead just write a context processor like above but instead of getting the default avatar from the DB, just have a static url to the image
from django.conf import settings
def default_avatar(request):
return {
'default_avatar' : '%simages/default_avatar.jpg' % settings.STATIC_URL
}

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!