I am trying to establish a blog using Django. I directly stored HTML into models. And I used {% autoescape off %} and {% endautoescape %} marks in HTML files that tells Python do not autoescape HTML code to string. Between the marks, I used codes like {{ article.content }} to load HTML codes stored in models.
The problem is that <img src="{% static 'img/dot.png' %}"> (HTML codes stored in models) will be displayed as {%%20static%20'img/dot.png'%20%}. The python codes won't be executed.
I feel helplessness. Does anyone have a good idea?
Here is a example of one template:
{% extends "base.html" %}
{% block content %}
{% load static %}
<div style='margin:0 auto;width:0px;height:0px;overflow:hidden;'>
<img src="{% static 'img/wechat.png' %}">
</div>
<header>
<div id="logo">
<span class="heading_desktop">You are browsing </span>Paradox<span class="heading_tablet"> , a personal site</span><span> of </span>Jiawei Lu<span class="heading_tablet"> since 2015</span><span class="phone_h">. Happy<script>document.write(" " + whatDay());</script>.</span>
</div>
<nav>
<ul>
<li>Articles</li>
<li>Portfolio</li>
<li>Jiawei Lu</li>
</ul>
</nav>
<hr class="red">
</header>
<div id="breadcrumb" class="article">
Articles → {{ article.title }}
</div>
<div id="wrapper">
<article>
<h1 class="article">{{ article.title }}</h1>
<div id="post_info">
<p>Published on {{ article.timestamp }}<!--<span> | </span>--></p>
<!-- Category inside article <p>Category 1Category 2<span> | </span></p> -->
<!-- Share inside article <p>Share: Email/Linkedin</p> -->
</div>
<div id="post_content" class="article">
{% autoescape off %}
{{ article.content }}
{% endautoescape %}
</div>
</article>
</div>
</div>
{% endblock %}
article.content: HTML Codes, like
<h1>Test</h1>
<img src="{% static 'img/dot.png' %}">
This doesn't really have anything to do with autoescaping. When Django outputs a variable, it doesn't do anything to interpret whatever is in that variable; so putting template tags into a model field won't work.
You would need to do something to render that data yourself manually; perhaps a custom template tag, or a model method, that uses the Template API to instantiate a template object and call its render method.
Related
(included website image) Essentially, on my website it displays the "Browse Topics" as well as the list of Topics indented as though it is 3fr(It is navigation so it should be on the left) while the "2 Rooms Available" and their contents are displayed beneath but as 1fr. . X.X
Home.html Code
{% extends 'main.html' %}
{% block content %}
<style>
.home-container{
display: grid;
grid-template-columns: 1fr 3fr;
}
</style>
<div class="home-container">
<div>
<h3>Browse Topics</h3>
<hr>
<div>
All
</div>
{% for topic in topics %}
<div>
{{topic.name}}
</div>
{% endfor %}
</div>
<div>
<h5>{{room_count}} rooms available</h5>
Create Room
<div>
{% for room in rooms %}
<div>
Edit
Delete
<span>#{{room.host.username}}</span>
<h5>{{room.id}} -- {{room.name}}</h5>
<small>{{room.topic.name}}</small>
<hr>
</div>
{% endfor %}
</div>
</div>
</div>
{% endblock content %}
Website Image
When I remove the browse topic column then the other column moves to the 3fr spot.
SOmething commandeering the 1fr column
Main.html File
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-9'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>StudyBud</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
</head>
<body>
{% include 'navbar.html' %}
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li></li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% block content %}
{% endblock content %}
</body>
</html>
Navbar.html File
<a href="/">
<h1>LOGO</h1>
</a>
<form method="GET" action="{% url 'home' %}">
<input type="text" name="q" placeholder="Search Rooms..." />
</form>
<a href="{% url 'login' %}">Login<a/>
<hr>
To start with - these divs seem to have gotten out of synch. They are closing off your home container too early. Try removing the last .
{% endfor %}
</div>
</div>
If you just put the raw html you have provided into a .html file and test, that seems to behave as you'd expect, with topic in 1fr and rooms in 3fr. If browse topics is still in your 3fr region, you may need to check your main.html template to see if something else is interfering.
Edit after additional files provided
<a href="{% url 'login' %}">Login<a/>
See the closing <a/> tag in your navbar file? That is mucking up everything. Replace it with </a>
I have a number of apps that each have their own intro section. This intro section has quite a few lines of HTML and only a few lines are adjusted for each app (Think title and intro). I would like this intro section to live at the project level (where the navbar template lives), but I can't find a way to pass template variables from the app to the project.
All of my apps(about 15) follow this template scheme:
app_base.html extends project base.html
app_base.html has an {% include %} to pull in app_intro.html
all <app_unique_templates>.html that are called by <app>/views.py, extend the app_base.html
To reiterate, how can I pass a template variable from /views.py to project base.html template using my app template scheme? If I can't use this scheme, can I adjust it in a way that will allow me to accomplish this?
Thank you all in advance!
views.py:
def add_app_context(view_context):
app_context = {
'app_name': 'Material Database',
'app_desc': 'Long String goes Here For Application Description',
'doc_link': '#',
}
view_context.update(app_context)
return view_context
class MaterialList(ListView):
model = Material
context_object_name = 'materials'
def get_context_data(self):
context = super().get_context_data()
context['pagetitle'] = 'Material List'
context['intro_btn_link'] = '/materials/new'
context['intro_btn_name'] = 'Create New Material'
return add_app_context(context)
app_base.html:
{% extends "mjd_tools/base.html" %}
{% load staticfiles %}
{% block body %}
<link rel="stylesheet" href="{% static 'mat_db/css/style.css' %}">
{% include "mat_db/app_intro.html" %}
{% block list %}{% endblock list %}
{% block form %}{% endblock form %}
<script src="{% static 'mat_db/js/scripts.js' %}"></script>
{% endblock body %}
app_intro.html(this is what I have to repeat for each app).
<div class="row">
<div class="col-sm-8">
<h1>{{ app_name }}</h1>
</div>
</div>
<hr>
<div class="row">
<div class="col-sm-8">
<p>
{{ app_desc }}
</p>
</div>
<div class="col-auto ml-auto">
<a class="btn btn-warning" role="button" href="{{ doc_link }}">Documentation</a>
</div>
</div>
<hr>
<div class="row">
<div class="col-sm text-center">
<h4>
<span>{{ pagetitle }}</span>
{% if intro_btn_name %}
<a class="btn btn-primary btn-sm pull-right" role="button"
href="{{ intro_btn_link }}">{{ intro_btn_name }}</a>
</h4>
{% endif %}
</div>
</div>
<hr>
I noticed that when i input a link into for loop in my templates that it gets injected into the first, lower elements. Il illustrate it below:
Base template:
<html>
<head></head>
<body>
{% block content %}
{% endblock %}
</body>
</html>
template which extends Base template
{% extends 'base.html'%}
{% block content %}
{% if elem_list %}
<ul>
{for elem in elem_list}
<li> <a class="bob" href="">
<div class="div1">
<div class="subdiv"></div>
</div>
<div class="div2">
<div class="subdiv"></div>
</div>
</a> </li>
{% endfor %}
</ul>
{% endif %}
{% endblock %}
and the output i get on my page
<html>
<head></head>
<body>
<ul>
<a class="bob" href="">
<li> <a class="bob" href="">
<div class="div1">
<a class="bob" href=""></a>
<div class="subdiv"><a class="bob" href=""></a></div>
<div class="subdiv"></div>
</div>
<div class="div2">
<a class="bob" href=""></a>
<div class="subdiv"><a class="bob" href=""></a></div>
<div class="subdiv"></div>
</div>
</a></li>
</ul>
</body>
</html>
Is this some kind of feature Django has? How can i stop it?
This has nothing at all to do with Django.
Your HTML is invalid, since an inline element like a cannot contain a block element like div.
You are presumably viewing the generated HTML via your browser's developer tools, which is doing its very best to interpret your broken HTML.
Somebody can help me how to solve this problem, why my templatetags isn't rendered in the template? but, only rendered as None instead.
Previously I working with Django==1.10.4.
1. templatetags/total_tags.py, I already created __init__.py inside this folder.
from django import template
from myapp.models import Category
register = template.Library()
#register.simple_tag
def total_categories():
"""
{% load total_tags %}
{% total_categories %}
used in: `includes/menus_dashboard.html`
"""
print(Category.objects.all()) # this worked well
Category.objects.all().count()
2. myapp/dashboard.html
{% extends "base.html" %}
{% load i18n %}
{% block title %}{% trans "Dashboard" %} :: {{ block.super }}{% endblock %}
{% block content %}
<div class="ui two column stackable grid">
<div class="four wide column dashboard-menu">
{% include "includes/menus_dashboard.html" %}
</div>
</div>
{% endblock %}
3. includes/menus_dashboard.html
The templatetags of {% total_topics %} is similiar with {% total_categories %}
{% load total_tags %}
<div class="ui fluid large inverted vertical pointing menu">
<a class="active item">
Dashboard
</a>
<a class="item">
Categories <div class="ui small label">{% total_categories %}</div>
</a>
<a class="item">
Topics <div class="ui small label">{% total_topics %}</div>
</a>
<a class="item">
Moderators <div class="ui small label">2</div>
</a>
<div class="item">
<div class="ui icon input">
<input type="text" placeholder="Search threads...">
<i class="search icon"></i>
</div>
</div>
</div>
Another idea, I tried like this answer: https://stackoverflow.com/a/12143011. and handle it with #register.assignment_tag, but still doesn't work well and only None instead.
It seems if I use {% extends "base.html" %} it inherits the template correctly but the navbar doesn't use bootstrap.
If I use {% extends "bootstrap/base.html" %} it doesn't even work. I don't get errors but it just sets the title to Index and then the page is blank.
Another note: The only way I've gotten the navbar to show up is directly putting it inside index.html and using {% extends "bootstrap/base.html" %}
I am using Flask Web Development by Miguel Grinberg and the code is identical except the obvious content.
What am I doing wrong? And does anyone have good resources for slowly jumping into Flask that doesn't just dive in head first? I'm having trouble understanding the little nitpicky details.
base.html:
{% extends "bootstrap/base.html" %}
<html>
<head>
{% block head %}
<title>{% block title %}{% endblock %} - MyFlask</title>
{% endblock %}
</head>
<body>
{% block navbar %}
<div class="navbar navbar-inverse" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Navbar</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">MyFlask</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>Home</li>
<li></li>
</ul>
</div>
</div>
</div>
{% endblock %}
{% block content %}
<div class="container">
{% block page_content %}{% endblock %}
</div>
{% endblock %}
</body>
</html>
index.html:
{% extends "base.html" %}
{% block title %}Index{% endblock %}
{% block page_content %}
<h3>Session info:</h3>
<p><b>Browser:</b> {{ browser }}</p>
{% endblock %}
When using the template inheritance it is common to define the structure of the layout in the base template, and then provide the specific details of each child template in the blocks (like content, page_content, etc).
In the above example where the base template itself is a child template (of "bootstrap/base.html"), the same pattern can be used.
Instead of defining HTML tags (like <html>, <head>, etc.) it's better to use the corresponding blocks. Flask bootstrap defines such blocks corresponding to each of these HTML tags, where child templates can override.
So if you change the base.html template as follows, then the index template can use the layout defined in bootstrap/base:
{% extends "bootstrap/base.html" %}
{% block head %}
{{ super() }}
<title>{% block title %}{% endblock %} - MyFlask</title>
{% endblock %}
{% block navbar %}
<div class="navbar navbar-inverse" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Navbar</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">MyFlask</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>Home</li>
<li></li>
</ul>
</div>
</div>
</div>
{% endblock %}
{% block content %}
<div class="container">
{% block page_content %}{% endblock %}
</div>
{% endblock %}
Note that in the head block, we are using super() to bring whatever Flask bootstrap has defined in the head block (could be loading CSS, JS files, etc.). This allows the base.html template to customize the head section. However if you do not require this control and only want to specify the title of the page, then you can avoid overwriting head block and just define the title block. To do this change base.html file to start like:
{% extends "bootstrap/base.html" %}
{% block title %}{% block page_name %}{% endblock %} - MyFlask{% endblock %}
Removing {% block head %} ... section.
And then modify your index.html template to define the page_name block instead of title:
{% extends "base.html" %}
{% block page_name %}Index{% endblock %}
{% block page_content %}
<h3>Session info:</h3>
<p><b>Browser:</b> {{ browser }}</p>
{% endblock %}
Now the title of the index page will be "Index - MyFlask", so you could have a common suffix for the title of all the pages.
Or if you need each page to have their own specific title, you may define the title block in there, overriding the title block in base.html.