Django Python base.html for all templates - python

In my root directory I have a template and inside that template follow by a base.html that would be my main layout for my custom admin site.
In my templates/admin/base.html I have this code.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Layout Page</title>
</head>
<body>
{% block content %}
{% endblock %}
</body>
</html>
I want this base.html to be present in all my app templates.
I have an app users in my mysite project that its the index.html page.
inside my users/views.
from django.shortcuts import render
def index(request):
return render(request, 'users/index.html')
Inside my templates/users/index.html I have this.
{% extends "admin/layout.html" %}
{% block content %}
<h1>Hello World</h1>
{% endblock %}
I get an error:
TemplateDoesNotExist at /
I come from a node.js background so I have no idea if this is even a good practice. I have came across many tutorials explaining the use of templates inside an app but non explaining outside the app.
My understanding was that django bundles all templates into one.
Thanks in advance.

I figure it out. I need to add the global template my project settings.
'DIRS': [
os.path.join(BASE_DIR, 'templates')
],

Related

What structure to generate reports using Jinja2?

I have some Python in Jupyter notebooks that creates pivot tables and some graphs from data. I now want to make PDF reports from this data and I'm looking at making HTML with Jinja2 and converting that to PDF.
I get that Jinja can have a base template and child templates that inherit from it. What I want is a base template that I can render that pulls HTML in from other files (so the base template doesn't get huge and I can debug smaller pieces).
What's the best way to achieve this?
Good evening,
In your case, what I would do is having a folder with your templates.
For example:
templates
|- base.html
|- my_template.html
|- another_template.html
Include
A solution is to use include:
For example in your base.html you would have:
<html>
<head>
</head>
<body>
{% include ['my_template.html', 'another_template.html'] %}
</body>
</html>
Here we include the results of rendering my_template.html and another_template.html in your base.html template.
You will have to give to your render function all the parameters needed for all the HTML templates you want to render.
Extends
With jinja2 you can also do what you want by using the extends capacity.
So let's say you have a template base.html of the type:
<html>
<head>
</head>
<body>
{% block core %}
{{ content }}
{% endblock %}
</body>
</html>
Here, we have a block named core.
You can then in another template extend the base template and replace the core block by something else, for example:
{% extends "base.html" %}
{% block core %}
<h1>Hello world</h1>
{% endblock %}
Unfortunately as you can see it means that if you want various HTML pieces you will have to do several extends.
You can have another template which is going to extend the previous template which extend the base one.
Manual
The last solution which is in my opinion not recommended, but for the sake of it I will expose it here:
Have a base.html of the kind:
<html>
<head>
</head>
<body>
{% for html in list_html_to_render %}
{{ html }}
{% endfor %}
</body>
</html>
Then we don't use Jinja2 anymore in this case, but we render each html contained in the list_html_to_render passed to the render function.
I hope it helps.
Have a lovely day,
My best regards.

Rendering different templates to the same URL pattern in Django

My question is similar to Same URL in multiple views in Django, but I am not rendering templates on the basis of user_authentication, but rather on the basis of JavaScript enabled or disabled in the browser.
What I am trying to do?
I am trying to render the index.html page if JavaScript is enabled in the browser, otherwise I want to render jsDisabled.html page if it's disabled and both of the pages should be rendered on the same URL pattern, for example:
localhost:8000 should either render index.html if JavaScript is enabled in the browser or it should render jsDisabled.html page if JavaScript is disabled.
Note: I am checking if JavaScript is disabled in the browser by using the <noscript> tag which will run when JavaScript is disabled.
Here is my code so far:
base.html:
{% load staticfiles %}
<!DOCTYPE html>
<html>
<head>
</head>
<body class="noJs">
...
abc
...
<noscript>
<style type="text/css">
.noJs {
display: none;
}
</style>
<meta http-equiv="refresh" content="{% ulr 'index' 1 %}"> /* This should render jsDisabled.html page on the same URL which is 'localhost:8000' */
</noscript>
</body>
</html>
urls.py:
from django.conf.urls import include, url
from django.contrib import admin
from . import views
urlpatterns = [
...
url(r'^(?P<flag>[0-1])$', views.index, name='index'),
]
views.py:
from django.shortcuts import render
def index(request, flag):
if (flag):
return render(request, 'jsDisabled.html')
else:
return render(request, 'index.html')
Depending on your Django version you may need to specify TEMPLATE_DIR = in settings.py (in newer versions this isn't required).
Here is some helpful information on template and tag logic:
Main/templates/myapp/base.html
Main/templates/myapp/index.html
Main/templates/myapp/includes/yes_js.html
Main/templates/myapp/includes/no_js.html
base.html:
{% load staticfiles %}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
{% block content %}
{% endblock %}
</body>
</html>
index.html:
{% extends 'myapp/base.html' %}
{% load staticfiles %}
{% block content %}
<noscript>
{% include 'no_js.html' %}
</noscript>
{% include 'yes_js.html' %}
{% endblock %}
After a lot of debugging I finally found the solution :) And here it is:
base.html:
{% load staticfiles %}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div class="noJs">
...
abc
...
</div>
<noscript>
<style type="text/css">
.noJs {
display: none;
}
</style>
{% include 'includes/jsDisabled.html' %}
</noscript>
</body>
</html>
urls.py
from django.conf.urls import include, url
from django.contrib import admin
from . import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^articles/', include('articles.urls')),
url(r'^contact/', include('contact.urls')),
url(r'^temp/',views.temp, name="temp"),
url(r'^$', views.index, name='index'),
]
views.py:
from django.shortcuts import render
def index(request):
return render(request,'index.html')
def temp(request):
return render(request,'temp.html')
I included the include built-in template tag as {% include 'includes/jsDisabled.html' %} suggested by #noes1s by creating a folder named includes inside the templates folder and placing jsDisabled.html inside of it.

Using static files in a Django template

I'm trying to get a file that's in my media directory to appear on an HTML template. I'm using the "Tango with Django" book as a tutorial.
Here is my settings.py:
MEDIA_DIR = os.path.join(BASE_DIR, 'media')
MEDIA_ROOT = MEDIA_DIR
MEDIA_URL = '/media/'
Here is views.py:
def about(request):
return render(request, 'rango/about.html', )
And my about.html template:
<!DOCTYPE html>
{%load staticfiles%}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>About</title>
</head>
<body>
<h1>This is the about page</h1>
<img src="{{MEDIA_URL}} {{cat.jpg}}"
alt="cats are funny"/>
<div>
Index
</div>
</body>
</html>
I know I must be missing something very obvious, but can't figure it out for the life of me!
The {{MEDIA_URL}} tag is deprecated. Use the {% get_media_prefix %} tag, instead.
<img src="{% get_media_prefix %}cat.jpg" alt="cats are funny"/>
From the documentation:
Similar to the get_static_prefix, get_media_prefix populates a template variable with the media prefix MEDIA_URL.
When rendered, that src attribute will be equivalent to /media/cat.jpg. You may want to consider using STATIC_ROOT in your settings.py, instead, along with the {% static %} tag:
<img src="{% static 'cat.jpg' %}" alt="cats are funny"/>
I think the problems should be errors in format.
Try the following two revisions:
1. in your render(), change "return render(request, 'rango/about.html', )" to "return render(request, 'rango/about.html') by deleting the last comma;
2. in your template file about.html, change .

While using flask in python, I am not able to get the 'extend' feature to work properly

I'm new to programming. I decided to try to create a web app using flask, python, and HTML. I set up three files; two HTML and one python:
This is the HTML file that should have information replaced (didntwork.html):
<!doctype html>
<html>
<head>
<title>My Webpage</title>
</head>
<body>
<h3>Information:</h3>
{% block body %}{% endblock %}
</body>
</html>
.
This is the file that should input information to the first (connection.html):
{% extends 'didntwork.html' %}
{% block body %}
<h4>information content</h4>
{% endblock %}
.
Finally, this is the logic for the flask app in python (main.py):
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/')
def index():
return render_template('didntwork.html')
if __name__ == '__main__':
app.run(debug=True)
Unfortunately, the extends in the second HTML file does not seem to be recognized, and the information in its block will not be replaced in the first HTML file (didntwork.html).
This is the output:
The expected outcome should append an h4 tag to the body with the phrase 'information content'.
Any help would be appreciated, thanks.
The problem is the {% extends 'didntwork.html' %}. From what I can tell the file that contains this code:
<!doctype html>
<html>
<head>
<title>My Webpage</title>
</head>
<body>
<h3>Information:</h3>
{% block body %}{% endblock %}
</body>
</html>
is your connection.html file.
You are extending to the same file you're rendering (didntwork.html). You have to change the extends line to extend your base html, connection.html in this case.
Use this code in your didntwork.html:
{% extends 'connection.html' %}
{% block body %}
<h4>information content</h4>
{% endblock %}
You can find more information in Template Inheritance
UPDATE BASE ON CLARIFICATION
You're rendering the wrong file in your route.
You should render the connection.html and this will extends your didntwork.html file.

Django template inheritance delivers no css?

In my django project there are some mysterious (at least for me as a beinner) outputs I don't understand while working in my development environment.
I wanted to have a base template which includes a stylesheet in a static media folder...this works so far...but just for the address http://localhost/ all the other urls have a template which inherits from the base template.
Now the stylesheet of http://localhost/ looks nice...if i go to http://localhost/hello/ the included stylesheet has a whole html DOM structure with body, doctype etc. why is that? He somehow parses a html site instead of taking the css file...
Here my code: Any ideas?
urls.py:
from django.views.static import *
from django.conf import settings
admin.autodiscover()
urlpatterns = patterns('',
('^$',home_view),
('^hello/$', hello),
(r'^admin/', include(admin.site.urls)),
('^useragent/$',ua_display_good1),
(r'^media/(?P<path>.*)$', 'django.views.static.serve',
)
views.py
from django.http import HttpResponse
from django.shortcuts import render_to_response
def hello(request):
pagetitle = "Hello World"
return render_to_response('hello.tpl', {'pagetitle': pagetitle})
def home_view(request):
pagetitle = "Something"
return render_to_response('home.tpl', {'pagetitle': pagetitle})
def ua_display_good1(request):
try:
ua = request.META['REMOTE_ADDR']
except KeyError:
ua = 'unknown'
return render_to_response('base.tpl',{'ageone': ua})
base template:
<!DOCTYPE html>
<html lang="de">
<meta name="description=" content="{{metadescription}}">
<head>
<link rel="stylesheet" type="text/css" href="media/style.css">
<title>{% block title %}{{pagetitle}}{% endblock %}</title>
</head>
<body>
<h1>{% block h1 %}{{ageone}}{% endblock %}</h1>
{% block content %}{% endblock %}
{% block footer %}{% include "footer.tpl" %}
{% endblock %}
</body>
</html>
hello template:
{% extends "base.tpl" %}
{% block h1 %}Home{% endblock %}
{% block content %}Welcome{% endblock %}
Probably because you have a relative reference to the CSS file.
Try changing:
<link rel="stylesheet" type="text/css" href="media/style.css">
to
<link rel="stylesheet" type="text/css" href="/media/style.css">
so it always look in the root for media/style.css
Now you have set the link to css as relative "media/style.css". In home it resolves to "/media/style.css" but in hello it resolves to "/hello/media/style.css" (which gives the hello page).
Just use absolute css link like this: "/media/style.css".
The proper way to include the style sheets would be
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}style.css">
if this still wont work ....my css file name is Stylesheet.css and i linked it as css/Stylesheet.css ..it wasnt working... then i changed it to css/Stylesheet.CSS ..and it worked
Change href="media/style.css" to href="media/style.CSS" and it will work.

Categories

Resources