I am building a little web application in Python 3.5, using Flask 0.11.1 and Flask-Admin 1.4.2.
Instead of using Flask-Admin as an administrative interface (only used by administrators of the website), I want it to be used by all the users of the website (to take profit of its awesome CRUD generation with forms using Select2 JS lib, inline forms, list views with filtering, etc.).
With that in mind, I want to override the list view template to be more user-friendly. For that, I am doing the following.
First, in my view I override list_template:
from flask_admin.contrib.sqla import ModelView
class FriendView(ModelView):
list_template = 'friend/list.html'
...
Then, I write the friend/list.html file by extending admin/model/list.html and overriding the block model_list_table defined in it:
{% extends 'admin/model/list.html' %}
{% block model_list_table %}
{% for row in data %}
<div class="col-xs-6 col-sm-4 col-md-3">
{% include 'friend/panel.html' %}
</div>
{% endfor %}
{% endblock %}
The panel.html file represents a Bootstrap panel illustrating each Friend:
<div class="panel panel-success">
<div class="panel-heading">
This friend is named {{ row.name }}.
</div>
<div class="panel-body">
{% block list_row_actions_column scoped %}
{{ super() }}
{% endblock %}
</div>
<div class="panel-footer">
...
</div>
</div>
Here is the problem: as you can see, I use in panel.html the block list_row_actions_column, which is a Jinja block defined in admin/model/list.html.
Of course, this raises the following error:
jinja2.exceptions.UndefinedError: there is no parent block called 'list_row_actions_column'.
because the file panel.html is not extending admin/model/list.html.
I have tried to define panel as a Jinja macro and to import it in friend/list.html, this raises the same error...
I know that I could simply not separate the panel in another file, however my friend/list.html is pretty big, and I think it is a good thing to do it that way, for sake of readibility and decoupling.
Does someone have an idea about how I can proceed?
Thanks,
Edouard
just make an html file and write single block of code in html file then include that file into that particular location where you want to need that code. that is the best method without use of any #block or #micro and for every block of code use a new html file and use this file as a function by including it on that place.
Related
I have a very basic template (basic_template.html), and want to fill in the with data formatted using another partial template. The basic_template.html might contain several things formatted using the partial template.
How should I structure the code in views.py?
The reason I am doing this is that later on the will be filled using Ajax. Am I doing this right?
You can do:
<div class="basic">
{% include "main/includes/subtemplate.html" %}
</div>
where subtemplate.html is another Django template. In this subtemplate.html you can put the HTML that would be obtained with Ajax.
You can also include the template multiple times:
<div class="basic">
{% for item in items %}
{% include "main/includes/subtemplate.html" %}
{% endfor %}
</div>
You can do this using a block. Blocks are a Django Template tag which will override sections of a template you extend. I've included an example below.
basic_template.html
<body>
{% block 'body' %}
{% endblock %}
</body>
template you want to include: (i.e. example.html)
{% extends 'basic_template.html' %}
{% block 'body' %}
/* HTML goes here */
{% endblock %}
views.py:
return render_to_response(template='example.html', context, context_instance)
Doing this will load basic_template.html, but replace everything inside of {% block 'body' %} {% endblock %} in basic_template.html with whatever is contained within {% block 'body' %} {% endblock %}.
You can read more about blocks and template inheritance in the Django Docs
There are mainly 2 ways (2 easy ones)
1:
In base html put
{% include "myapp/sub.html" %}
And just write html code inside your sub.html file
2:
https://docs.djangoproject.com/en/dev/ref/templates/language/#template-inheritance
I just wanted to add differences of extend and include.
Both template and include can use models inserted in current app.
Template is for global usage by your any app. Include is for use in certain apps.
For ex: you want to insert Image Slider to your homepage and about page but nowhere else. You can create Slider app with its own model for convenience and import its model and include in that pages.
If you used template for this example, you would create 2 templates one with slider and everything else other template have.
I'm using ng-include like this
HTML
<div ng-app="myapp" ng-controller="myctrl" ng-include="/static/html/main.html"></div>
main.html
{% extends "app\base.html" %}
{% block content %}
<div ng-controller="myctrl1">
some content
</div>
{% endblock %}
base.html
<div ng-controller="myapp2">some content </div>
but this is not working, it is showing an errorr "SyntaxError: Unexpected token % at Object.parse (native)"
Please suggest me a better way to implement this.
I don't quite know what you're trying to do here. Angular templates and Django ones are quite different, even if they superficially share the same {{ var }} syntax. You can't inherit an Angular template from a Django one, or vice versa.
But there's no reason to want to do that anyway. Angular is already loading the template as a partial, which means it will be inserted into the div in base.html. There's no need for inheritance here at all.
Here is my original source code.
{% extends "base.html" %}
{% block css %}
{{ super() }}
<link rel="stylesheet" type="text/css" href="/static/css/comic.css">
{% endblock %}
{% block content %}
<div id="comic">
<div id="nav-container">
{{ comic_path(int(panel_id) + 1) }}
{{ str(int('3')) }}
{{ int(panel_id) + 1 }}
{{ int(panel_id) }}
{{ isinstance(panel_id,basestring) }}
</div>
<img id="panel" src="{{ comic_path(panel_id) }}">
</div>
{% endblock %}
Focus on the nav-container id. All of those python blocks were attempted but all of them fail with a 500 Internal Server Error - an error in the application, and no errors are produced in the logs.
I don't have any further information that is relavent (the problem is truly isolated to those 5 example {{ }} blocks) , but I can answer any questions to help me figure it out.
Jinja2 template code is not Python code, only Python-like. As such you are limited to functions listed in the built-in filters and functions, plus whatever extra globals you explicitly added to template engine.
str() is not listed, nor is isinstance() and probably comic_path() is not either. str() is really not needed as that is what {{ ... }} interpolation already does, but there is a string() filter that does the same.
Generally speaking, you pass already processed data to your template, including the result of the comic_path() call.
Sometimes it is advantageous to add a function as a custom filter or as a new global. If you are using a ready-rolled integration of Jinja2 with a web framework, do look in the documentation for that framework to see if it offers an easy way to add filters or globals within its context.
If compic_path() is already a global, then int would be used like:
{{ comic_path(panel_id|int + 1) }}
as it is a filter, not a function.
I have a problem with replacing part of website built in django with another content.
I have a code like
<section id='main_page'>
<div id="main_div">
<--! include kek.html content here -->
</div>
</section>
and I'd like to replace this comment with html placed in another html file.
I tried
def home(request):
return HttpResponse(render_to_string(
'index.html',{'bla':kek.html},
))
while in in index.html was
<section id='main_page'>
<div id="main_div">
{{ bla }}
</div>
</section>
but, it doesn't seem to work that way. I'm kinda new to django and python and I can't find any solution.
No, that wouldn't even run (kek.html is not defined in the view, so it's a NameError).
You can use the {% include %} tag in the template for this:
<section id='main_page'>
<div id="main_div">
{% include 'kek.html' %}
</div>
</section>
You should really do the Django tutorial, which explains how templates work (among other things).
Edit after comment
In that case you should treat the name of the include as a variable and pass it from the view:
{% include template_to_include %}
...
return render_to_response(
'index.html', {'template_to_include': 'kek.html'},
)
Note the quotes.
When using Django templates, should I have some templates that act like "subroutines", so to speak, or should I generate HTML from within my code in these cases?
For example, I have a template with several lists of names, each of which I want to turn into a select. Should I have a template that renders the name_list variable into a select, and do something like this:
#in the view:
return {'name_list_1': name_list_1,
'name_list_2': name_list_2,
'name_list_3': name_list_3}
#in the template:
{% with name_list_1 as name_list %}
{% include "sub_name_list_select.html" %}
{% endwith %}
{% with name_list_2 as name_list %}
{% include "sub_name_list_select.html" %}
{% endwith %}
{% with name_list_3 as name_list %}
{% include "sub_name_list_select.html" %}
{% endwith %}
Or should I have a function in my code, name_list_to_select_html, which does the same job, and do this:
return {'name_list_1_html': name_list_to_select_html(name_list_1),
'name_list_2_html': name_list_to_select_html(name_list_2),
'name_list_3_html': name_list_to_select_html(name_list_3)}
#in the template:
{{ name_list_1_html|safe }}
{{ name_list_2_html|safe }}
{{ name_list_3_html|safe }}
Or are both of these wrong and I am getting the philosophy totally wrong?
Additional question: in terms of speed, is it slow to constantly include templates? Is that a bonus point for the in-code html generation?
Generally, HTML should only be generated in the templating system or directly related code. That keeps the view of the data completely separate from the business and functional logic. I feel that's a proper separation of concerns. Go with your first solution.
As for performance, Django should probably take around the same amount of time running either code. But it has built-in view and template fragment caching if you know those segments of code don't need to be regenerated on every request.