Since my last question here: Python images display
I understood that from all the answers I got the glob.glob could be the only one in the direction I need.
However where I am stuck right now is here:
I can create a list with all the filenames in my media directory by using glob.glob:
all = glob.glob("/Path_to_MEDIA/*/*.jpg")
But how can I use that and create a VERY SIMPLE image display with one next button that calls files in my MEDIA_ROOT and displays them.
What I know is:
I have a Template which looks something like the default directory index:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Language" content="en-us" />
<meta name="robots" content="NONE,NOARCHIVE" />
<title>Index of {{ directory }}</title>
</head>
<body>
<h1>Index of {{ directory }}</h1>
<ul>
{% ifnotequal directory "/" %}
<li>../</li>
{% endifnotequal %}
{% for f in file_list %}
<li>{{ f }}</li>
{% endfor %}
</ul>
</body>
</html>
I need to create a def in my views that feeds the list from glob.glob to this or similar template.
What I dont know:
How does this def in the view have to look like?
And here:
What do I have to write to display one image, sound in a browser?
What do I have to write to display a LIST of images, sounds?
Thanks for the time!
Make a direct-to-template url with extra-context in urls.py:
from django.views.generic.simple import direct_to_template
...
url(r'^whatever', direct_to_template,
{ 'template':'foo.html', 'extra_context': {'files':myfiles} }
name='whatever' ),
Where myfiles above is a list/tuple of your files. However, make sure to format your file list in terms of MEDIA_URL instead of based on MEDIA_PATH. For example:
myfiles = [ 'relative/path/foo.jpg',
'http://static.mysite.com/absolute/path/bar.jpg' ]
Though, obviously generated from the filesystem in your case, not a hardcoded list. And you could do the work in a view rather than using direct-to-template -- just make sure to put the files key/value into your context:
def myview( request ... ):
context = RequestContext(request)
context[files]=myfiles
return render_to_respone( ..., context_instance=context )
Then, in your template foo.html:
{% for file in files %}
<img src='YOUR_MEDIA_URL_HERE/{{ file }}' />
{% endfor %}
Related
In my folder Templates I created 2 html files:
main.html
user.html
The structure of the main.html is:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DJANGO</title>
</head>
<body>
{% block userinfo %}
{% endblock userinfo %}
</body>
</html>
The structure of the user.html is:
{% extends "main.html" %}
{% block userinfo %}
<h2>John Doe</h2>
<p>Explorer of life.</p>
{% endblock userinfo %}
I don't understand why
<h2>John Doe</h2>
<p>Explorer of life.</p>
doesn't appear in the browser when I call main.html
I have tried writing in this way too
{% extends "main.html" %}
{% block userinfo %}
<h2>John Doe</h2>
<p>Explorer of life.</p>
{% endblock %}
without user in the endblock but it does not work.
In settings.py file in Templates list and DIR list I added:
os.path.join(BASE_DIR,'templates'),
and I importend os too.
In views.py file that I've created I have written
from django.shortcuts import render
from django.http import HttpResponse
def main(request):
return render(request,'main.html')
In urls.py file that I've created I have written
from django.urls import path
from . import views
urlpatterns = [
path('main/',views.main,name='')
]
When I call the page with http://localhost:8000/main/
I don't have any error. The only problem is that the page is blank.
And If I try to add some text in main.html it appers on the screen, but the content from user.html doesn't appear.
Can someone help me?
When you render main.html directly, your user.html gets ignored.
If you render user.html from django, you will get expected result.
To inject user.html contents to main.html you should use something like {% include "user.html" %} insead of blocks statement.
Extension in templates follows the same logic that class inheritance, it goes the way down not up.
Once said, main is the base template and you will never see the content of templates in which you are extending, its the opposite, you will see the content of the base template (the one you are extending for) in the child template (the one that has the extends).
I guess the behavior that you are expecting to have is the one that gives the include tag
main.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DJANGO</title>
</head>
<body>
{% include "user.html" %}
</body>
</html>
user.html
<h2>John Doe</h2>
<p>Explorer of life.</p>
I want to disable cahce in Flask-Admin panel, where i displaying some images. For exmaple, i have 1 image in my DB (actually, just uri to an image). If i delete this image, and then upload a new one, the cache will show me deleted image.
To escape this moment, i need disable caching. But, also, i want disable it on all Flask-Admin pages.
{% extends 'admin/master.html' %}
{% block head_meta %}
{{super()}}
<meta http-equiv='cache-control' content='no-cache'>
<meta http-equiv='expires' content='0'>
<meta http-equiv='pragma' content='no-cache'>
{% endblock head_meta %}
I know if i save code above as index.html, it applies only to index admin page panel.
But, as i also said above, i want to disable caching on all pages.
Found some information about it. If you want to edit your CUSTOM view, you should add these variables:
list_template = 'list.html'
create_template = 'create.html'
edit_template = 'edit.html'
Where list.html responsible for list with all your records and so on.
Also, you should create template, where you put all your code to append to existing Flask-Admin. In my case, it looks like this:
{% extends 'admin/model/list.html' %}
{% block head_meta %}
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
{{ super() }}
{% endblock head_meta %}
above is example of disabling cache on page where all records are show
I have this function which gets data from an API and then uses Jinja2 to insert this data into an HTML file. I want this data to show up in my newsletter.html and be sent as an email. Everything works fine apart from
this happening:
Here are some relevant snippets:
Getting the data as list and templating with Jinja:
# movie_finder.py
movie_list = []
for item in now_playing['results']:
if genre_id in item['genre_ids']:
movie_list.append(item['original_title'])
print movie_list
# Create jinja2 environment
try:
env = Environment(loader=PackageLoader('movie_finder', 'templates'))
template = env.get_template('newsletter.html')
rend = template.render(info=movie_list)
print "Templating successful"
except:
print "Templating fail"
return "Templating fail"
find_movies_with_genre(API_KEY, 878)
In the script that sends the email (which otherwise works fine), I simply do:
from scifi_finder import find_movies_with_genre
Template:
<!-- Newsletter template by https://github.com/derekpunsalan/-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width"/>
<!-- For development, pass document through inliner -->
<link rel="stylesheet" href="css/simple.css">
<style type="text/css">
output print movie_list:
[u'Thor: Ragnarok', u'Blade Runner 2049', u'War for the Planet of the Apes', u'Geostorm']
You are not passing the variables correctly when calling render(), here is what you are doing:
template.render(info=movie_list)
You are passing a variable info, yet in your template, you are referring to movie_list:
{% for item in movie_list %}
{{ item[0] }}
{{ item[1] }}
{% endfor %}
This will not work, you need to refer to the variable you are passing, personally I prefer it this way:
template.render(movie_list=movie_list)
...and in template...
{% for item in movie_list %}
{{ item[0] }}
{{ item[1] }}
{% endfor %}
...as you have it already. You could just as well use...
{% for item in info %}
{{ item[0] }}
{{ item[1] }}
{% endfor %}
...in your template and keep your function call as it is, but personally I find the first variant less confusing when I read it again weeks later.
I've got a simple flask app, with a templates folder with a bunch of html files that are created by a separate program. I want to (1) serve each of these html files by hitting localhost:8888/<html_filename> and
(2) create a directory with hyperlinks to these endpoints on my main / endpoint.
Thoughts on how I could get a jinja template to create links to those endpoints? Heres what I've been thinking.
Flask App:
#app.route('/')
def index():
reports = [f_name for f_name in os.listdir("templates") if f_name.endswith(".html")]
return render_template("index.html", reports=reports)
#app.route('/<report>')
def render_report(report):
return render_template(report+'.html')
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Report Directory</title>
</head>
<body>
<ul>
{% for r in reports %}
<li>
{{ r }}
</li>
{% endfor %}
</ul>
</body>
</html>
Off the top of my head and not tested in any way define a route along the lines of the following:
#route("/<string:slug>/", methods=['GET'])
def page(self, slug):
if slug_exists_as_a_html_file(slug):
return render_template(slug)
abort(404)
The function (or inline it) )slug_exists_as_a_html_file needs to return True if the slug matches a valid html template file, otherwise false.
To generate your report listing use something like :
<!DOCTYPE html>
<html lang="en">
<head>
<title>Report Directory</title>
</head>
<body>
<ul>
{% for r in reports %}
<li>
{{ r }}
</li>
{% endfor %}
</ul>
</body>
</html>
This question already has answers here:
Is it possible to use AngularJS with the Jinja2 template engine?
(2 answers)
Closed 6 years ago.
I am trying to implement AngularJs to my flask project. In my app.py I have this code to render a test site:
#app.route('/test/')
def test():
return render_template('test.html')
And in the test.html I have this:
<!DOCTYPE html>
<html lang="en" data-ng-app>
<head>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<title>Flask-Triangle - Tutorial</title>
</head>
<body>
<label>Name:</label>
<input type="text" data-ng-model="yourName" placeholder="Enter a name here">
<hr>
<h1>Hello {{ yourName }}!</h1>
</body>
</html>
When I type in the input field nothing is happen..
I have checked that the angular.min.js is correctly loaded.
Is there something I have to do in app.py to get this work?
Flask uses jinja as its templating language which also uses {{ variable }}
so when flask renders the templates {{ yourname }} just becomes an empty string since yourname is not a context variable in the current render
to fix this you can use flask-triangle
http://flask-triangle.readthedocs.org/en/develop/tutorial/part1.html
which provides a template filter
{{ yourname | angular }} that will ensure the template is rendered correct for angular
you could also use escaped brackets inside the brackets (but this is much uglier I think)
{{ '{{ yourname }}' }}
Another way to fix this is that you can wrap the entire test.html contents with {% raw %} at the top, and {% endraw %} at the bottom. This will tell jinja not to do anything special in this. This way would only be good if you are not planning on using jinja at all. Using this would also make it a bit nicer to write with, as you no longer have to add in the fixes that Joran Beasley suggested.
Example:
{% raw %}
<!DOCTYPE html>
<html>
<head>
<!-- HEADER STUFF -->
</head>
<body>
<!-- Normal AngularJS code and syntax -->
</body>
</html>
{% endraw %}