Passing template variable to parent in Django - python

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>

Related

Django basic ModelForm not showing choices

Using Django tutorial, I built a basic ModelForm with choice fields:
One field (Shirt size) - is not showing choices
Second field - not showing at all
I can't find the reason, anywhere I checked it seems like I'm doing things right, but obviously I'm not.
Thank you.
The Result Form
views.py
def person(request):
if request.method == 'POST':
form = forms.PersonForm(request.POST)
if form.is_valid():
return HttpResponseRedirect('/thanks/')
else:
form = forms.PersonForm()
return render(request, 'development/form_template.html', {'form': form})
forms.py
class PersonForm(ModelForm):
class Meta:
model = models.Person
fields = '__all__'
models.py
class Person(models.Model):
SHIRT_SIZES = (
('S', 'Small'),
('M', 'Medium'),
('L', 'Large'),
)
name = models.CharField(max_length=60, default='Anonymous', help_text='Type your name.')
shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES)
medal_type = models.TextChoices('MedalType', 'GOLD SILVER BRONZE')
form_template.html
{% extends 'development/development_template.html' %}
{% block content %}
<div class="container">
<form action="/your-name/" method="post">
{% csrf_token %}
<table>
{{ form.as_table }}
</table>
<input type="submit" value="Submit">
</form>
</div>
{% endblock content %}
CSS files I'm using
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.css" type="text/css" rel="stylesheet" media="screen,projection"/>
<link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<link type="text/css" rel="stylesheet" href="{% static 'css/style.css' %}">
The problem was 100% the support of Materializecss design in select - for some reason it's not supporting select anymore.
I used bootstrap4 to execute the form pages:
(1) install: pip install django-bootstrap4
(2) add to INSTALLED_APPS = [..., 'bootstrap4',]
(3) edit your HTML form
Here's html for example:
{% extends 'adolim/adolim_template.html' %}
{% block content %}
{% load bootstrap4 %}
{# Load CSS and JavaScript #}
{% bootstrap_css %}
{% bootstrap_javascript jquery='full' %}
{# Display django.contrib.messages as Bootstrap alerts #}
{% bootstrap_messages %}
<div class="container" style="width:100%;" dir="rtl">
<div class="col s3 right">
</div>
<div class="col s6 right" dir="rtl">
<div class="container">
<div class="row"><br></div>
<h4 class="right">{{ page_title }}</h4>
<div class="row"><br></div>
<form dir="rtl" action="{% url 'adolim:add_order' %}" method="post" >
{% csrf_token %}
{% bootstrap_form form %}
<div class="col center">
{% buttons %}
<button class="btn-large waves-effect waves-light blue darken-1" type="submit" name="action">{{ page_title }} למערכת
<i class="material-icons right">send</i>
</button>
{% endbuttons %}
</div>
</form>
</div>
</div>
</div>
{% endblock content %}

How to pass Data to Flask_Admin's View's HTML?

I'm currently trying to populate widgets on the Flask_Admin Home Page with data from my Database.
However, I'm having trouble passing the data into the HTML. Here is my view, where I want to render accountBalance:
class MyView(BaseView):
accountBalance = 0
#expose('/')
def index(self, accountBalance, **kwargs):
self.accountBalance = accountBalance
return self.render('admin/index.html', accountBalance=accountBalance)
# And app code:
accountBalance = 10000
if __name__ == '__main__':
admin = Admin(app, name='MyAdmin', template_mode='bootstrap3')
admin.add_view(views.MyView(accountBalance))
app.run(host='0.0.0.0')
And here's the HTML/Jinja logic in admin/index.html, which tries to render the accountBalance I passed in above:
{% extends 'admin/master.html' %}
{% block head_css %}
{{ super() }}
<link href="{{ url_for('static', filename='sb-admin-2.css') }}" rel="stylesheet">
{% endblock head_css %}
{% block body %}
{{ super() }}
<div class="col-lg-3 col-md-6">
<div class="panel panel-primary">
<div class="panel-heading">
<div class="row">
<div class="col-xs-3">
<i class="fa fa-comments fa-5x"></i>
</div>
<div class="col-xs-9 text-right">
<div class="huge">This is your balance:</div>
<div> {% accountBalance %}</div>
</div>
</div>
</div>
</div>
</div>
{% endblock body %}
I've been following examples to try to get this to work, where the '{% accountBalance %}' in the HTML should be the value of accountBalance I'm trying to pass in, but to no prevail.
What am I doing wrong?
Use {{ accountBalance }}. {% .. %} is used for statements like for loop and if conditions.
From the documentation:
{% ... %} for Statements
{{ ... }} for Expressions to print to the template output

Django templatetags rendered as None in the template

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.

Python code between django "autoescape off" marks can not be executed

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.

How do I correctly inherit templates in flask that use bootstrap?

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.

Categories