Filling a template slot, content doesn't appear - python

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>

Related

Print a list in HTML file using Django

I want to print a list called formulario and I want to paste them into a html file using Django template language, although I'm not able to display that information in <li> tag. Is there sth am I missing?
views.py
from django.template import RequestContext
from django.http import HttpResponse
from django.shortcuts import render
import pandas as pd
formulario = ["Hola", "Hi"]
def formulario(request):
return render (request, "formulario/formulario.html",{
"formulario":formulario
})
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>Document</title>
</head>
<body>
<h1>Formulario !</h1>
<ul>
{% for formulario in formulario %}
<li>{formulario}</li>
{% endfor %}
</ul>
</body>
</html>
urls.py
from django.urls import path
from . import views
urlpatterns = [
path("index.html",views.index, name="index"),
path("financierofinanciamiento.html",views.financiamiento, name="financiamiento"),
path("financierobeneficio.html",views.beneficio, name="beneficio"),
path("tecnicoinfra.html",views.infra, name="infra"),
path("tecnicoequipo.html",views.equipo, name="equipo"),
path("tecnicoherramientas.html",views.herramientas, name="herramientas"),
path("tecnicomateriaprima.html",views.materiaprima, name="materiaprima"),
path("formulario.html",views.formulario, name="formulario"),
]
{% for item in formulario %}
<li>{{ item }}</li>
{% endfor %}

Python Flask - url_for{} not accessing static folder [duplicate]

This question already has an answer here:
Flask Python not loading main.css
(1 answer)
Closed 1 year ago.
Have a directory structure as follows:
Flask_project
-env
-src
--app2.py
-static
--css
---main.css
-templates
--base.html
--index.html
-app.py
If I load the page using app.py in the main folder, the main.css file is loaded fine using: python app.py. This works from the following file:
from flask import Flask, render_template, url_for # import
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
if __name__ == "__main__":
app.run(debug=True)
However, if I load app2.py using python3 src\app2.py which is in the \src folder as follows, and redirects the template_folder:
from flask import Flask, render_template, url_for # import
app = Flask(__name__, template_folder='../templates')
#app.route('/')
def index():
return render_template('index.html')
if __name__ == "__main__":
app.run(debug=True)
I am unable to load the css\main.css folder, I get the following error:
"GET /css/main.css HTTP/1.1" 404 -
I don't see why placing the app_whatever.py file in a sub directory (in this case \src) makes it unable to locate the main.css file?
For reference the base.html is as follows:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="{{url_for('static', filename='css/main.css') }}">
{% block head %}{% endblock %}
</head>
<body>
{% block body %}
{% endblock %}
</body>
</html>
And index.html is:
{% extends 'base.html' %}
{% block head %}
{% endblock %}
{% block body %}
<h1> Template </h1>
{% endblock %}
As mentioned in your second question, you need to define the location of your static-folder:
app = Flask(__name__, template_folder='../templates', static_folder='../static')

'str' object has no attribute 'method'

I am trying to access a request.method in a python view, but I'm getting the error
'str' object has no attribute 'method'
The really odd thing is that I can see no difference between how I set up this page and how I set up another similar page; yet that one works fine and this one does not.
The code I am using is as follows:
main/views.py:
from .alphabetize import alphabetize
from .forms import WordListForm
def alphabetize(request):
if request.method == "POST":
form = WordListForm(request.POST)
if form.is_valid():
word_list = alphabetize(form.cleaned_data['word_list'])
return render(request, 'main/alphabetize.html', {'form': form, 'word_list': word_list})
else:
form = WordListForm()
return render(request, 'main/alphabetize.html', {'form': form})
/main/forms.py
class WordListForm(forms.Form):
word_list = forms.CharField(label="Word List")
main/urls.py
from django.conf.urls import url
from main import views
urlpatterns = [
url(r'alphabetize', views.alphabetize, name='alphabetize'),
]
main/alphabetize.py
def alphabetize(s):
word_list = []
for word in s.split(','):
word_list.append(word.strip())
word_list.sort()
return ', '.join(word_list)
templates/main/alphabetize.html
{% extends "base.html" %}
{% block content %}
<form action="/alphabetize" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</form>
<p>Your list alphabetized: {{ alpha_list }}</p>
{% endblock content %}
/templates/base.html
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My Awesome Django Page</title>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link rel="stylesheet" href="{% static 'css/style.css' %}">
</head>
<body>
<div class="main">
{% block content %}{% endblock content %}
</div>
</body>
</html>
It seems that for some reason request is a string rather than an HttpRequest object, but I can't figure out why that would be.
You have two different functions called alphabetize; your view, and your utility function. As a result your view is calling itself, rather than the other function.
You should rename one of these.
Your view name overrides imported function alphabetize. Change view name to fix:
from .alphabetize import alphabetize
from .forms import WordListForm
def alphabetize_view(request):

Flask template extending issue

Flask template extension doesn't work for some reason.
I've created a basic flask app with the following file structure:
__init__.py is empty
The code from app.py is:
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/')
def index():
return render_template("index.html")
if (__name__ == "__main__"):
app.run()
The code from index.html is:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<h1>from index</h1>
{% block ext %}
{% endblock %}
</body>
</html>
The code from ext.html is:
{% extends "index.html" %}
{% block ext %}
<h2>from ext</h2>
{% endblock %}
When I run in command line python app.py it gives no errors or warnings, logs are just
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
127.0.0.1 - - [27/Sep/2017 14:48:40] "GET / HTTP/1.1" 200 -
But in the browser, the only output I have is "from index". So Flask doesn't see template extension from ext.html, and I don't see "from ext" in the browser. What's wrong here? Is there a typo somewhere?
You're rendering the wrong thing. Inheritance goes from child to parent; if you want the child template to be used, then that's what you need to call.
def index():
return render_template("ext.html")

Python images display Django

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 %}

Categories