Image not working while converting html to pdf - django

I want to convert one html page into pdf in django web- framework , everthing is working good except image .
Here is small snippet of HTML page which I want to convert into pdf
<div class="certi-description"> <img src="/media/certificate/icons/2.jpg" style="width: 12%;height: 25%;position: absolute; left: {{tag_logo_offset.0|add:'-355'}}px; top: {{tag_logo_offset.1|add:'-170'}}px;"><br>
<div style="position: absolute; left: {{tag_name_offset.0|add:'-355'}}px; top: {{tag_name_offset.1|add:'-170'}}px;"><div id="tag" ><center><font size="3" color="red">{{ tag_name}}</font><center></div></div><br><br>
<div style="position: absolute; left: {{comm_offset.0|add:'-355'}}px; top: {{comm_offset.1|add:'-170'}}px;"><span><font size="5" color="black">is hereby Rewarded to</font></span></div><br>
Here is code snippet in views.py
template = certi.generic_certificate.template_name
template_new = get_template(template)
context_dict = Context(context)
html = template_new.render(context_dict)
print html
result = StringIO.StringIO()
links = lambda uri, rel: os.path.join(base.MEDIA_ROOT, uri.replace(base.MEDIA_ROOT, ''))
print base.MEDIA_ROOT
pdf = pisa.pisaDocument(StringIO.StringIO(html.encode("UTF-8")),dest=result, link_callback=links)
if not pdf.err:
converted_pdf= HttpResponse(result.getvalue(), content_type='application/pdf')
converted_pdf['Content-Disposition'] = 'attachment; filename="certificate%s.pdf"'%certi_id
p = canvas.Canvas(converted_pdf)
p.showPage()
p.save()
pdf = result.getvalue()
result.close()
myfile = ContentFile(pdf)
Certificate.objects.filter(pk=certi_id).update(pdf_template = p)
converted_pdf.write(pdf)
return converted_pdf
base.py as my settings file :
MEDIA_ROOT = normpath(join(DJANGO_ROOT, 'media'))
MEDIA_URL = '/media/'
########## END MEDIA CONFIGURATION
AUTHENTICATION_BACKENDS = ('custom.backends.EmailOrUsernameModelBackend',)
########## STATIC FILE CONFIGURATION
STATIC_ROOT = normpath(join(DJANGO_ROOT, 'final_static'))
STATIC_URL = '/static/'
I have several images in /media/certificate/icons folder like 2.jpg which I am using in my html
Everthing is converting to pdf except image. I have checked all possible paths but still not working.
Please help to solve this issue.

Related

Vue.js are not displaying images from Django media folder

So, i have up and running Django server on localhost. There's is a Vue page, whick is authorized and able to fetch models data.
If i inspect page, i see that img element have correctly resolved URL, and image exsists and can be loaded.
As you can see, other model parameters (such as name and price) can be loaded.
def get_thumbnail(self):
if self.thumbnail:
return 'http:://127.0.0.1:8000/' + self.thumbnail.url
else:
if self.image:
self.thumbnail = self.make_thumbnail(self.image)
self.save()
return 'http:://127.0.0.1:8000/' + self.thumbnail.url
else:
return ''
Here's how I loading img.
<figure class="image mb-4">
<img v-bind:src="product.get_thumbnail" />
</figure>
I've checked media folder paths, and believe they are correct
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media/'
Also, if I am able to load image by the link gotten via page inspection, why can't it be loaded on page itself?
UPDATE:
I found the problem:
when I'm pointing at src

Upload a file in admin and then download from the website Django

I am trying to create a website, where customer can upload a file in an Admin section, and after any person can download this file from the website. Preferably any files like pdf, exe, doc (is it possible?) I am able to upload a file in Admin and it shows it on the website. It downloads the file with a correct name (saved in media) but shows a failure , file missing.
So far I have :
setting.py
STATIC_URL = '/static/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
models.py
class TEACHING(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
date_posted = models.DateTimeField(auto_now_add=True)
excercise = models.FileField(upload_to="files/", default='default value')
def __str__(self):
return self.title
views.py
def teaching(request):
context = { 'teaches' : TEACHING.objects.all()}
return render(request, 'blog/teaching.html', context)
urls.py
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root = settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)
teaching.html
{% for teach in teaches %}
<a href="{{ teach.excercise }}" download>Download</a>
{% endfor %}
Managing files docs
You should get URL from your File field
<a href="{{ teach.excercise.url }}" download>Download</a>
Hi You are not providing url in href, so please change your <a> with following way
<a href="{{ teach.excercise.url }}" download>Download</a>

Need help to render img in pdf from template using xhtml2pdf

I'm building a project were i need to get my data into pdf from a template (html), my problem is that the image is not apearing on pdf view.
This is my code:
class GeneratePdf_month(TemplateView):
template_name = "polls/info_month.html"
def get(self, request, *args, **kwargs):
## do some....
data = {
'cliente': cliente,
}
pdf = render_to_pdf(self.template_name, data)
return HttpResponse(pdf, content_type='application/pdf')
## and this is my html template
<head>
{% load staticfiles %}
<title>Detail</title>
<style>
table, th, td {
border: 1px solid black;
border-collapse: collapse;
padding: 10px;
}
</style>
</head>
<body>
<header>BlaBla<img src="{% static 'polls/images/image.png'%}"></header>
</body
Can someone help me?
If your are using xhtmltopdf you also need to provide a link_callback for being abble to display images:
def link_callback(uri, rel):
"""
Convert HTML URIs to absolute system paths so xhtml2pdf can access those
resources
"""
# use short variable names
sUrl = settings.STATIC_URL # Typically /static/
#static Root
sRoot = settings.STATIC_ROOT # Typically /home/userX/project_static/
mUrl = settings.MEDIA_URL # Typically /static/media/
mRoot = settings.MEDIA_ROOT # Typically /home/userX/project_static/media/
# convert URIs to absolute system paths
if uri.startswith(mUrl):
path = os.path.join(mRoot, uri.replace(mUrl, ""))
elif uri.startswith(sUrl):
path = os.path.join(sRoot, uri.replace(sUrl, ""))
else:
return uri # handle absolute uri (ie: http://some.tld/foo.png)
# make sure that file exists
if not os.path.isfile(path):
raise Exception(
'media URI must start with %s or %s' % (sUrl, mUrl)
)
return path
AND don't forget to add the link callback in your render_to_pdf:
def render_to_pdf(template_src, context_dict={}):
template = get_template(template_src)
html = template.render(context_dict)
result = BytesIO()
pdf = pisa.pisaDocument(BytesIO(html.encode("ISO-8859-1")), result, link_callback=link_callback)
if not pdf.err:
return HttpResponse(result.getvalue(), content_type='application/pdf')
return None
You also need to specify the height and widht inside the img tag like:
<img src="{% static 'polls/images/image.png'%}" alt="image" width="200" height="150" />
In settings.py don't forget to define your STATIC_URL AND STATIC_ROOT, MEDIA_URL AND MEDIA_ROOT
Like this for exemple:
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR,'project_name/static/')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR,'project_name/media/')
Then don't forget to run python manage.py collectstatic in the terminal
More info here: https://xhtml2pdf.readthedocs.io/en/latest/usage.html#using-xhtml2pdf-in-django
in views.py
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
path = os.path.join( BASE_DIR , 'static')
# send 'path' first in context
context = {'path':path , 'any':any }
in template
<img src="{{path}}\img\pic.png" >

Django templates - Image from media_root rendered in homepage, but not other pages

I have an image that renders on my homepage, but it doesn't on a different page using the same code. I figure the problem may be the difference my url path maybe? It's the only difference I can find. When I inspect each element, this is what I see:
Working image: /event/image.png
Broken Image: /event/media/image.png
I'm rendering the image like this in my template:
<img src="media/{{event.image}}" class="img-responsive" />
My model is just aa model.Image field and here are is my view for the Broken image page:
def event(request, product_id):
event = get_object_or_404(Event, id=product_id)
image = event.image
context = {'event':event, 'image':image}
template = 'tourney.html'
return render(request, template, context)
In my terminal, it says image not found. So how can I change my settings so that it looks in the right directory no matter which path I'm in? Here are my media settings:
if DEBUG:
MEDIA_URL = '/media/'
STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), 'static', 'static-only')
MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), 'static', 'media')
STATICFILES_DIRS = (
os.path.join(os.path.dirname(BASE_DIR), 'static', 'static'),
)
You need a leading slash: "/media/...".
However, even better would be to use the built-in property that gives you the full URL including MEDIA_URL:
<img src="{{ event.image.url }}" class="img-responsive">
Instead of building url by yourself, like media/{{event.image}}, let Django do that job for you:
<img src="{{ event.image.url }}" class="img-responsive" />
That way, Django will create proper URL, using MEDIA_URL from your settings. Be aware that your web server configuration must match that and serve images from MEDIA_ROOT on MEDIA_URL

Failing to show images in templates Django

I have problems showing images in my Django templates (I'm uploading the images from the admin application). I read the documentation and other posts about the upload_to and still couldn't figure it out. I tried this <img src="{{ a.image}}"/> in my template and then this <img src="{{MEDIA_URL}}{{ a.image}}"/> and same results. Here is my settings.py code :
MEDIA_ROOT = '/home/mohamed/code/eclipse workspace/skempi0/media'
MEDIA_URL = '/media/'
and finally, I tried the following in my models.py and I failed miserably:
image = models.ImageField(upload_to = "ads/")
image = models.ImageField(upload_to = ".")
and when I used image = models.ImageField(upload_to = MEDIA_URL) I got the following error
SuspiciousOperation at /admin/advertisments/banner/add/
Attempted access to '/media/cut.jpg' denied.
EDIT
Generated links are as follows :
<img src="./DSCN6671.JPG">
RE-EDIT
Here is my view:
def index(request):
spotlightAlbum = Album.objects.filter(spotlight = True)
spotlightSong = Song.objects.filter(spotlight = True).order_by('numberOfPlays')
homepage = Song.objects.filter(homepage = True).order_by('numberOfPlays')
ads = Banner.objects.all()
copyright = CopyrightPage.objects.get()
try:
user = User.objects.get(userSlug = "mohamed-turki")
playlists = UserPlaylist.objects.filter(owner = user.userFacebookId)
purchase = Purchase.objects.filter(userName = user.userFacebookId)
user.loginState = 1
user.save()
except:
user = None
playlists = None
context = {'copyright':copyright, 'ads':ads, 'spotlightSong':spotlightSong,'spotlightAlbum': spotlightAlbum, 'homepage':homepage, 'user':user, 'playlists':playlists, 'purchase':purchase }
return render_to_response('index.html',context,context_instance = RequestContext(request))
Could anybody tell me what am I doing wrong??
P.S I'm using Django 1.4
The path you provide in upload_to will be a relative path from the MEDIA_ROOT you set in your project's settings file (typically settings.py).
Your MEDIA_ROOT is where your uploaded media will be stored on disk while the MEDIA_URL is the URL from which Django will serve them.
So if your MEDIA_ROOT is /home/mohamed/code/eclipse workspace/skempi0/media and your model's image attribute is:
image = models.ImageField(upload_to = "ads/")
Then the final home on disk of your uploaded image will be /home/mohamed/code/eclipse workspace/skempi0/media/ads/whatever-you-named-your-file.ext and the URL it will be served from is /media/ads/whatever-you-named-your-file.ext
Setting your upload path to be settings.MEDIA_URL won't work because that's where the media is served FROM not where it is allowed to be stored on disk.
If you want to load your uploaded image in your templates just do this (replace whatever with the name of the variable sent from the view to the template that represents this object):
<img src="{{ whatever.image.url }}"/>
The image attribute on your model isn't actually an image, it's a Python class that represents an image. One of the methods on that ImageField class is .url() which constructs the path to the URL of the image taking into account how you set your MEDIA_URL in your project's settings. So the snippet above will generate HTML like this:
<img src="/media/ads/whatever-you-named-your-file.ext"/>
RequestContext() and settings.TEMPLATE_CONTEXT_PROCESSORS
Since the render_to_response() you are returning from your view is utilizing RequestContext() you need to make sure you have settings.TEMPLATE_CONTEXT_PROCESSORS set correctly. Check out the 1.4 docs for further clarification.
upload_to needs to be an absolute path to the directory, not the web url. So try this:
image = models.ImageField(upload_to = settings.MEDIA_ROOT)
in your templates, just use
<img src="{{ a.image.url }}">
First, I suggest to change the MEDIA_ROOT to be
MEDIA_ROOT = os.path.join(PROJECT_ROOT,'media')
this way you ensure the media directory path is right under your project root. Your MEDIA_URL is set up correctly, but it is not used when uploading a file. MEDIA_ROOT is.
Regarding the file upload, in your model set the field to be
image_field = models.ImageField('Image', upload_to='images/some_sub_folder')
Note that I didn't use neither a leading nor trailing forward slashes. The above will upload the image to PROJECT_ROOT/media/images/some_sub_folder/ with the filename and extension of the original file. Alternatively, you can alter the filename by using a callable - upload_to=filename_convetion - more info here.
In your template, you can access the image using
<img src="/media/{{ your_model.image_field }}" />
Hope this helps, cheers.
I know this question is old but I had the same problem and this solved in my case:
settings.py
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
PROJECT_DIR = os.path.dirname(__file__)
MEDIA_ROOT = os.path.join(PROJECT_DIR, "media")
MEDIA_URL = '/media/'
urls.py
Then, my urls.py was missing this line of code to discover the /media/ folder and show the content:
urlpatterns += staticfiles_urlpatterns()
urlpatterns = patterns('',
url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}, name="media_url"),
) + urlpatterns
Hope it can help someone.