Extending Django Admin templates - django

I try to modify django admin templates
I created custom template with the name corresponding to template, that I want to override.
I try the following
{% extends "admin/change_form.html" %}
<h1>HELLO</h1>
If I reload the page I dont see h1 tag.
If I try
{% extends "admin/change_form.html" %}
{% block field_sets %}
<h1>HELLO</h1>
{% endblock %}
I seen only h1 tag and dont see model's editing fields.
What have I do to see form and h1 tag in same time ?

This should work:
{% extends "admin/change_form.html" %}
{% block field_sets %}
{{ block.super }}
<h1>HELLO</h1>
{% endblock %}
You must call the block from the source change_form.html template. Do that with {{ block.super }} as shown above. You can, of course, reverse the order between super and h1 according to your needs.

Related

Django Template overriding

I was wondering, when using templates in django, I'm able to extend other base templates and override some of the blocks in the base template. so my question is when I override, would the code in the overridden block still get rendered then overridden, or would it never be run and only the new block is rendered?
Example:
base.html
{% block menu %}
{% for option in menu %}
...Create the menu entries
{% endfor %}
{% endblock menu %}
extender.html
{% extends base.html %}
{% block menu %}
... some other tags
{% endblock menu %}
In this case does the original for loop in the base.html run if it gets overridden?
As far as I know the block will be overwritten unless you want to preserve its code in your extended template.
If you want to preserve the original block you can use {{ block.super }}
base.html
[...]
<body>
{% block header %}
base header content
{% endblock %}
[...]
</body>
extended.html
{% extends "base.html" %}
{% block header %}
{{ block.super }}
new content added
{% endblock %}
[...]
G.

django template extend - all but one template

I have a piece of html that I want present in all pages, except one. If not for this page, I would have put it in the base.html and extended.
Is there a way other than putting the code individually in all the required pages?
From template-inheritance docs,
The template engine will notice the {% block %} tags in base.html and replace those blocks with the contents of the child template.
BUT
If the child template didn’t define the block, the value from the
parent template is used instead. Content within a {% block %} tag in a
parent template is always used as a fallback.
So in that case you can use {% block %} tag in the base.html.
{% block content %}
<!-- Your content here-->
{% endblock %}
You don't have to define that block in every template as the parent {% block %} is used as an fallback.
{% extends 'base.html' %}
So in your exceptional case just define that {% block %} tag with no data or something else.
{% extends 'base.html' %}
{% block content %}
<!-- Nothing goes here -->
{% endblock content %}
You can put it into a block that gets overridden with nothing in order to have it ignored. For example:
base.html
{% block content %}
<div>
This should show on all pages except for this one
</div>
{% endblock content %}
included-page.html (The div will be included on this page)
{% extends 'base.html' %}
ignored-page.html (The div will be ignored on this page)
{% extends 'base.html' %}
{% block content %}
{% endblock content %}

Compositional Templates Django

What is the best way to create modular templates?
For example, if I have something like this:
#base file:
{header}
{block content}
{footer}
#main file:
{extends base}
{block content definition}
#product file:
{extends base}
{block content definition}
This is the django way from what I understand - filling in the blanks.
Now, my question is what if I needed a page like this:
{header}
{main}
{product}
{footer}
Basically, the main, and product are both inside the base file. I could try a deep inherit (a page that has main, which then consecutively loads product) but that does not work since the files both define 'content', and that is not possible in Django
You need do two templates "_main.html" and "_product.html" which don't extend base, just their own content.
After that you can use them via include tag https://docs.djangoproject.com/en/dev/ref/templates/builtins/#include
#main.html file:
{% extends 'base.html' %}
{% block content %}
{% include '_main.html' %}
{% endblock %}
#product.html file:
{% extends 'base.html' %}
{% block content %}
{% include '_product.html' %}
{% endblock %}
#and what you want:
{% extends 'base.html' %}
{% block content %}
{% include '_main.html' %}
{% include '_product.html' %}
{% endblock %}
{% block footer %}
{% endblock %}

Django: with tag outside blocks

It seems like the 'with' tag is not working if it is declared outside of a block as this:
{% extends 'base.html' %}
{% with my_var=1 %}
{% block test1 %}
{{my_var}}
{% endblock %}
{% block test2 %}
{{my_var}}
{% endblock %}
{% endwith %}
The template above simply displays nothing since my_var is NOT passed inside those blocks.
How can I overcome this?
I came to Django from using Tornado with Jinja2 and I was being driven insane by the inability to set variables that (a) could be defined in the template (not view) and (b) would be available in the base template that this derives from. Looking at a little four-line piece of code from django-libs, I was able to rig up something like this that worked well. Here is an example of a title string that should appear in various blocks.
settings.py -- add to TEMPLATES (Django 1.10+)
TEMPLATES = {
...
builtins = ['mysite...wherever...templatetags',]
}
mysite.whereever.templatetags.py
from django import template
register = template.Library()
#register.simple_tag(takes_context=True)
def setvar(context, key, value):
context.dicts[0][key] = value
return ''
base.html
{% block settings %}
{% comment %}
Put this at the TOP of the template before
any blocks that use variables.
{% endcomment %}
{% endblock settings %}
<html>
<head><title>{{title}}</title></head>
<body><h1>My Site: {{title}}</h1>
{% block body %}
{% endblock body %}
</body></html>
menu.html -- a template that does not set 'title' in views:
{% extends "base.html" %}
{% block settings %}
{{ block.super }} {% comment %}optional{% endcomment %}
{% setvar 'title' 'Menu' %}
{% endblock %}
{% block body %}
<ul><li>Fish</li><li>Steak</li></ul>
{% endblock %}
Now the title will appear in two places in the HTML even though it is defined in the derived template but appears in the top template.

How to use {% with %} along with {% include %} -- Django

For example, I have a template file called:
filter.html
{{ title }}
code...
What I'd like to do is, on a separate template:
{% with "Filter by Types" as title %}
{% include "filter.html" %}
{% endwith %}
Currently it can't be done. Could someone explain why that is and an alternative way to achieve this?
Background context:
The app base is used for multiple sites. The site admin would only be able to edit the template files to give them a degree of customization, but not the views.py or other core files. So the {{ title }} variable can't really be sent by the views.py.
I might be missing something but why not just use extends and block tags?
base.html
{% block title %}Default title{% endblock %}
filter.html
{% extends "base.html" %}
{% block title %}Filter by Types{% endblock %}
Check out the documentation on extends, blocks and template inheritance for more info.