I am creating a program that generates a chart, and then displays the chart on the webpage. I want each chart generated to have a unique filename. However, once that unique filename is generated, I don't know how to refer to it within the html file.
I use this to create a random filename starting with "chart" in the "images" folder. This parts works fine.
basename = "images/chart"
suffix = str(uuid.uuid4())
filename = "_".join([basename, suffix])
plt.savefig(filename)
I then have this in the html file, but don't know how to modify to add the random suffix part of the name that was just generated.
<img src="{{ url_for('static', filename = '/images/chart.png') }}">
It is hard to say without knowing more about the structure of your application, but one approach might be to change the template to something like
<img src="{{url}}">
and then calling it with
render_template('template.html', url=url_for('static', filename))
I'm no flask expert, but my instinct would be to avoid putting too much Python code — things like the url_for call — in the templates, because I do not want to mix program logic with presentation.
Related
I'm working on a Django app which parses xlsx input, processes series of REST API queries and returns the result of the queries as a table in one of my django templates. The HTML code containing the results table is generated with Pandas.to_html() functionality. The HTML code is stored in a variable ("table") and passed to the html template, where it is displayed as {{ table | safe }}. This mechanism works just fine. However, I'm now struggling to add a button which would generate a pdf file to be downloaded by the user.
NOTE: I'm aware it would probably make more sense to use JS to render the PDF on the client side, but at the moment the point is to avoid doing so.
Upon some research, I decided to go with the django-easy-pdf library. I based my solution on the example included in the documentation, but so far to no avail.
In urls.py:
urlpatterns = [
[...]
path('result.pdf', views.PDFView.as_view(), name='PDFview'),
]
In views.py:
class PDFView(PDFTemplateView):
template_name = 'whitelist/listresult.html'
table = None
def get_context_data(self, **kwargs):
return super(PDFView, self).get_context_data(pagesize='A4', title='Hi there!', table=self.table, date=date.today)
Please note that the template "listresult.html" is the one expecting the {{ table }} variable.
Last but not least, in the very listresult.html (where I want to place the button to render the PDF file), I added a simple button object:
<a class="btn btn-secondary btn-lg" href="{% url 'PDFview' table %}">Download PDF</a>
My expectation was that since I'm sending the "table" variable along with the request for PDF url, the view would process it nicely and prompt the user with a download pop-up for the PDF file looking exactly (or almost exactly) as the page which presented the result in the first place. However, I'm cought in a vicious circle where if I add "table" to the url reference on the site I get an error during template rendering for the very website displaying results (NoReverseMatch for ..., Reverse for 'PDFview' with arguments '['table' contents go here] not found). On the other hand, if I remove the "table" argument from the url reference, the results website renders OK with the "Download PDF" button, but upon clicking it I'm left with a Runtime Error (since context is missing).
I'm 97% confident my mistake is ostentatiously stupid, but after x hours of struggle I'm ready for StackOverflow's judgement.
I have this in config.toml:
baseURL = "https://my-username.github.io/blog/"
and there is a static file at static/img/foo.png.
Now, in content/posts/bar.md, I have the following content:
---
title: "Bar"
---
![foo](img/foo.png)
The picture isn't showing after I started the hugo server, so I inspected elements, and found out that Hugo generated the following URL for it:
http://localhost:1313/blog/posts/bar/img/hireme.png
This is not what I expect; it should be
http://localhost:1313/blog/img/hireme.png
When I use ![foo](/blog/img/foo.png), the picture is displayed correctly, but this is quite strange: /blog/ is part of baseURL, why do I need to type it again?
I think you should use <base> tag to make baseURL for static files.
Add the <base> tag into <head>:
<base href="{{ .Site.BaseURL }}">
And then you can insert image in post like this:
![Foo image](img/foo.jpg)
References:
https://www.w3schools.com/tags/tag_base.asp
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
In a simple setup where your site lives in the domain's root, a absolute reference to the image would be a standard practice. However, in your case where the site is nested, a more crafty solution is necessary.
I suggest using a shortcode to solve your dilemma. Just simply create a shortcode that takes in a resource file path and spits out the desired absolute path every time. The advantage to this approach is flexibility for future resource relocation to a cdn for example.
Your markdown code will be something like this:
![foo]({{< resource url="img/foo.png" >}})
Your shortcode template will be something like this:
{{ .Site.BaseURL }}{{ .Get "url" }}
Create a file named 'resource.html' in 'layouts/shortcodes/' folder, and drop in the shortcode template code above.
So when you decide you want to switch to a cdn you could easily do this:
://cdn.example.com/{{ .Get "url" }}
I'm installed Flask-images for resizing some images. My code are like this:
<img src = '{{url_for('showimages', filename = market.thumbnail, width=100, height=100, mode='crop')}}'>
showimages:
#app.route('/image/user/<filename>')
def showthumbnail(filename):
return send_from_directory(app.config['UPLOAD_FOLDER'], filename)
There are nothing happens and my Chrome devaloper tools said image's url like this:
<img src="/image/user/Untitled-1.png?width=100&height=100&mode=crop">
I know there is another way instead url_for - resized_img_src().
I'm set IMAGES_PATH= os.path.join(APP_ROOT, 'images/').
However this configuration does not work and when I use resized_img_src(), only got broken image icon. I don't have a clue how can fix this.
+Is there any other easy ways to resizing uploaded images?
Your template uses showimages whereas your Flask Python code shows showthumnails, I'll assume this is typo and code actually uses same as template.
Are these really the quote characters you are using in your template? You need to use the single and double quotes or escape the inner single ones. Try this instead:
<img src="{{url_for('showimages', filename=market.thumbnail, width=100, height=100, mode='crop')}}">
I'm really new to Django. I'm having difficulty displaying images based on their name and according to the url pattern.
So basically the url consists of several variables within them and I want to be able to use that to fetch a particular image that is named with those variables.
Example:
localhost:8080/farm/chicken
this would fetch an image inside of my ../static/images/ folder and get:
farm_chicken.jpg
Another example:
localhost:8080/zoo/alligator
would get:
zoo_alligator.jpg
I can fetch the url parameters. So, should I make these image names within my views.py file and pass the names (zoo_alligator) into a context to be retrieved by the template later on? Would this be the correct way?
Thank you for your advice everybody! I appreciate all the help!
You won't actually do something like that, in general. What you should do is to send the image as a context variable from your view function to your template.
If you are using your url node to determine which picture to show, then in your corresponding view function, you are actually using "alligator" or "chicken" to load up the corresponding Animal class.
Once the correct animal object is instantiated, you could send this animal object to your django template and load in the image using a snippet similar to this:-
Like this:-
{% if animal.get_latest_medium_url %}
<img id="animal_image" class="img-rounded left" src="/media/{{ animal_image }}" />
{% endif %}
The get_latest_medium_url is a method in my Merchant class and it computes the url there.
So, should I make these image names within my views.py file and pass
the names (zoo_alligator) into a context to be retrieved by the
template later on? Would this be the correct way?
Sure, this is one way to do it. Something like this:
(r'show/(?P<in_path>.*)$','someapp.image_view')
Then in image_view:
def image_view(request,in_path):
img = in_path.replace('/','_')+'.jpg'
return render(request,'some_template.html',{'path':img})
However, as your view is very simple - you can pass the path directly to the template from urls.py, using direct_to_template:
from django.views.generic.simple import direct_to_template
(r'show/(?P<in_path>.*)$',direct_to_template,{'template':'some_template.html'})
In some_template.html:
<img src="{{ params.in_path }}">
The problem is that you won't get your string formatting done as the default filters do not have a "replace" function. You can easily write a custom filter:
#register.filter
#stringfilter
def format_path(the_path):
return the_path.replace('/','_')+'.jpg'
Then modify the template:
<img src="{{ params.in_path|format_path }}">
You should read the documentation on writing custom filters and tags for more details including where to store the filter code to make sure django can find it.
In a Satchmo Store, I need to attach a small .png (a barcode) to an email that django sends on completion of the order. The email is formatted in HTML using send_order_confirmation() which calls send_store_mail() (both part of satchmo.) Neither of these functions offer the ability to attach a file (I think) so should I just re-write them? I was wondering if it is possible/better to do this using signals. Maybe rendering_store_mail() ?
By the way, the barcode would be dynamically generated, so there's no way of having a link to a file on a server somewhere.
Many thanks,
Thomas
well I too had to add extra infos to the confirmation emails, only text though. So this would be the very easy way to add extra-stuff to emails using signals, which IMHO, is the best approach to do it. Always use signals if you can avoid overriding the satchmo-core ;-)
define your listener to add some context for the rendering. In this case I'm adding the contents of an extra notes field, and the barcode for this order, supposing there is a function named get_barcode_img(<order>), to the context. I'm supposing here too, that the get_barcode_img function would return not just a png, but something like a MIMEImage (like from email.MIMEImage import MIMEImage) to be able to just include it inline. Also, there might be more infos needed, like a MIME-header for the img.
# localsite/payment/listeners.py
def add_extra_context_to_store_mail(sender,
send_mail_args={}, context={}, **kwargs):
if not 'order' in context:
return
context['barcode_header'] = get_barcode_header(context['order'])
context['barcode_img'] = get_barcode_img(context['order'])
context['notes'] = context['order'].notes
connect the listener to the signal somewhere where the code will be "discovered" for sure, like models.py:
# localsite/payment/models.py
from satchmo_store.shop.signals import rendering_store_mail, order_notice_sender
rendering_store_mail.connect(payment_listeners.add_extra_context_to_store_mail, sender=order_notice_sender)
override the templates locally (e.g. order_placed_notice.html) to add the new context. Be aware where you put your templates, as the path is essential for django to take your new template instead of the satchmo's one. In this case, starting from your project's root-path, there could be a templates-folder and inside it, there must be exactly the same path as in the satchmo-folder. E.g. /templates/shop/email/order_placed_notice.html ... this can be applied for any "valid" templates-folder inside an app. It's up to you to decide, where/how the templates should be organized.
<!-- templates/shop/email/order_placed_notice.html -->
<!DOCTYPE ...><html>
<head>
<!-- include the image-header here somewhere??? -->
<title></title>
</head>
<body>
...
Your comments:
{{ notes }}
Barcode:
{{ barcode_img }}"