Django admin reuse header - python

I would like to reuse the header of the django admin page in my custom view so I can use the "view site, change password and logout" so I won't have to recode that part.
Is it possible to extend only the header part?

Probably you can't. Because these are integral part of admin/base.html template. So instead, you can create a new base template and copy the header section from this admin/base.html. Like this:
{% load i18n static %}<!DOCTYPE html>
{% get_current_language as LANGUAGE_CODE %}{% get_current_language_bidi as LANGUAGE_BIDI %}
<html lang="{{ LANGUAGE_CODE|default:"en-us" }}" {% if LANGUAGE_BIDI %}dir="rtl"{% endif %}>
<head>
<title>{% block title %}{% endblock %}</title>
<link rel="stylesheet" type="text/css" href="{% block stylesheet %}{% static "admin/css/base.css" %}{% endblock %}">
{% block extrastyle %}{% endblock %}
{% if LANGUAGE_BIDI %}<link rel="stylesheet" type="text/css" href="{% block stylesheet_rtl %}{% static "admin/css/rtl.css" %}{% endblock %}">{% endif %}
{% block extrahead %}{% endblock %}
{% block responsive %}
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0">
<link rel="stylesheet" type="text/css" href="{% static "admin/css/responsive.css" %}">
{% if LANGUAGE_BIDI %}<link rel="stylesheet" type="text/css" href="{% static "admin/css/responsive_rtl.css" %}">{% endif %}
{% endblock %}
{% block blockbots %}<meta name="robots" content="NONE,NOARCHIVE">{% endblock %}
</head>
{% load i18n %}
<body class="{% if is_popup %}popup {% endif %}{% block bodyclass %}{% endblock %}"
data-admin-utc-offset="{% now "Z" %}">
<!-- Container -->
<div id="container">
{% if not is_popup %}
<!-- Header -->
<div id="header">
<div id="branding">
{% block branding %}{% endblock %}
</div>
{% block usertools %}
{% if has_permission %}
<div id="user-tools">
{% block welcome-msg %}
{% trans 'Welcome,' %}
<strong>{% firstof user.get_short_name user.get_username %}</strong>.
{% endblock %}
{% block userlinks %}
{% if site_url %}
{% trans 'View site' %} /
{% endif %}
{% if user.is_active and user.is_staff %}
{% url 'django-admindocs-docroot' as docsroot %}
{% if docsroot %}
{% trans 'Documentation' %} /
{% endif %}
{% endif %}
{% if user.has_usable_password %}
{% trans 'Change password' %} /
{% endif %}
{% trans 'Log out' %}
{% endblock %}
</div>
{% endif %}
{% endblock %}
{% block nav-global %}{% endblock %}
</div>
<!-- END Header -->
</div>
<!-- END Container -->
</body>
</html>

Related

django changeform_view extra_context

I'm trying to learn on model admin template customization.
I need that custom template can read some data stored/passed in 'extra_context'
admin.py
from django.contrib import admin
from .models import MailTemplate
# Register your models here.
class MailTemplateAdmin(admin.ModelAdmin):
change_form_template = 'change_form_htmx.html'
def changeform_view(self,request, object_id=None, form_url="", extra_context=None):
extra_context = extra_context or {}
extra_context['myvar']='this is myvar'
return super(MailTemplateAdmin, self).changeform_view(request, object_id=object_id, form_url=form_url, extra_context=extra_context)
admin.site.register(MailTemplate,MailTemplateAdmin)
template 'change_form_htmx.html'
{% extends "admin/base_site.html" %}
{% load i18n admin_urls static admin_modify %}
{% block extrahead %}{{ block.super }}
<script src="{% url 'admin:jsi18n' %}"></script>
{{ media }}
{% endblock %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" href="{% static "admin/css/forms.css" %}">{% endblock %}
{% block coltype %}colM{% endblock %}
{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} change-form{% endblock %}
{% if not is_popup %}
{% block breadcrumbs %}
<div class="breadcrumbs">
{% translate 'Home' %}
› {{ opts.app_config.verbose_name }}
› {% if has_view_permission %}{{ opts.verbose_name_plural|capfirst }}{% else %}{{ opts.verbose_name_plural|capfirst }}{% endif %}
› {% if add %}{% blocktranslate with name=opts.verbose_name %}Add {{ name }}{% endblocktranslate %}{% else %}{{ original|truncatewords:"18" }}{% endif %}
</div>
{% endblock %}
{% endif %}
{% block content %}<div id="content-main">
<!--- add htmx -->
<script src="https://unpkg.com/htmx.org#1.6.0"></script>
{% block object-tools %}
{% if change and not is_popup %}
<ul class="object-tools">
{% block object-tools-items %}
{% change_form_object_tools %}
{% endblock %}
</ul>
{% endif %}
{% endblock %}
<form {% if has_file_field %}enctype="multipart/form-data" {% endif %}{% if form_url %}action="{{ form_url }}" {% endif %}method="post" id="{{ opts.model_name }}_form" novalidate>{% csrf_token %}{% block form_top %}{% endblock %}
<div>
{% if is_popup %}<input type="hidden" name="{{ is_popup_var }}" value="1">{% endif %}
{% if to_field %}<input type="hidden" name="{{ to_field_var }}" value="{{ to_field }}">{% endif %}
{% if save_on_top %}{% block submit_buttons_top %}{% submit_row %}{% endblock %}{% endif %}
{% if errors %}
<p class="errornote">
{% blocktranslate count counter=errors|length %}Please correct the error below.{% plural %}Please correct the errors below.{% endblocktranslate %}
</p>
{{ adminform.form.non_field_errors }}
{% endif %}
{% block field_sets %}
{% for fieldset in adminform %}
{% include "admin/includes/fieldset.html" %}
{% endfor %}
{% endblock %}
{% block after_field_sets %}{% endblock %}
{% block inline_field_sets %}
{% for inline_admin_formset in inline_admin_formsets %}
{% include inline_admin_formset.opts.template %}
{% endfor %}
{% endblock %}
<div id="some_buttons">
<!-- here we have button for add and delete row-->
from extra_context = {{ extra_context.myvar }}
</div>
{% block after_related_objects %}{% endblock %}
{% block submit_buttons_bottom %}{% submit_row %}{% endblock %}
{% block admin_change_form_document_ready %}
<script id="django-admin-form-add-constants"
src="{% static 'admin/js/change_form.js' %}"
{% if adminform and add %}
data-model-name="{{ opts.model_name }}"
{% endif %}
async>
</script>
{% endblock %}
{# JavaScript for prepopulated fields #}
{% prepopulated_fields_js %}
</div>
</form></div>
{% endblock %}
There is no error occured, but the extra_content['myval'] is not showed.
Kindly please tell how is the proper way to send extra_context from ModelAdmin and read it in template.
Sincerely
-bino-
Argghh my vault.
It work now.
I replace (in template)
{{ extra_context.myvar }}
with
{{myvar}}

NoReverseMatch at /forum/

I am trying to implement the django-registration-redux and have used templates written by Andres available at https://github.com/macdhuibh/django-registration-templates . But the problem is whever i run anything i get the NoReverseMatch Error.
I tried to render the base.html template to check the error and i got error on line 12.
and the base.html is as
{% load i18n %}
<html lang="en">
<head>
<link rel="stylesheet" href="{{ STATIC_URL }}style.css" />
<title>{% block title %}User test{% endblock %}</title>
</head>
<body>
<div id="header">
{% block header %}
{% trans "Home" %} |
{% if user.is_authenticated %}
{% trans "Logged in" %}: {{ user.username }}
({% trans "Log out" %} |
{% trans "Change password" %})
{% else %}
{% trans "Log in" %}
{% endif %}
<hr />
{% endblock %}
</div>
<div id="content">
{% block content %}{% endblock %}
</div>
<div id="footer">
{% block footer %}
<hr />
{% endblock %}
</div>
</body>
</html>
index.html is as
{% extends "base.html" %}
{% load i18n %}
{% block content %}
Index page
{% endblock %}
and the urls.py as
from django.conf.urls import url
from . import views
app_name = 'forum'
urlpatterns = [
url(r'^$', views.index, name='index'),
]
and i get the error as in the below image:
Error
You probably need to specify the app name in the tag:
{% trans "Home" %}

Why is the title displaying in the body of the page when using Flask?

Everything was working fine including the title until I went to add an icon in. Upon manually creating the <head> and calling {{ super() }} to bring in Bootstrap's black magic, the title now displays above the navigation bar.
base.html
{% extends "bootstrap/base.html" %}
{% block head %}
{{ super() }}
{% block title %}{% block page_name %}{% endblock %} - MyFlask{% endblock %}
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
{% endblock %}
<body>
{% block navbar %}
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#">MyFlask</a>
</div>
</div>
</nav>
{% endblock %}
</body>
index.html
{% extends "base.html" %}
{% block page_name%}Index{% endblock %}
When you use the super() function in a block, you are adding new contents to that block instead of replacing the original content. So when you called super() in the head block, Jinja2 inserted the head block's content from the bootstrap/base.html:
<head>
{%- block head %}
<title>{% block title %}{% endblock title %}</title>
{%- block metas %}
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{%- endblock metas %}
{%- block styles %}
<!-- Bootstrap -->
<link href="{{bootstrap_find_resource('css/bootstrap.css', cdn='bootstrap')}}" rel="stylesheet">
{%- endblock styles %}
{%- endblock head %}
</head>
After that you added a new title block, so now you have two of them, and that is the problem.
The solution is easy, don't define a new head block in base.html, just override the title block, and append your favicon lines to the styles:
{% extends "bootstrap/base.html" %}
{% block title %}{% block page_name %}{% endblock %} - MyFlask{% endblock %}
{%- block styles %}
{{ super() }}
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
{% endblock %}
{% block navbar %}
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#">MyFlask</a>
</div>
</div>
</nav>
{% endblock %}
I suspect this doesn't answer your question directly, but perhaps a better way of achieving this outcome is to pass in the page title from the view.
base.html
{% block title %}
{% if title %}
{{title}} - MyFlask
{% else %}
MyFlask
{% endif %}
{% endblock %}
views.py
#app.route('/', methods=['GET'])
def index():
return render_template("index.html", title='Index')

Jinja2 templates inheritance

With Jinja2, do all blocks need to be defined in the base template from which all other templates extend? For instance, given the following templates:
<-- ultra_base.j2 -->
<head>
</head>
<body>
{% block content %}{% endblock %}
{% block extra_js %} {% endblock %}
</body>
and
<-- child.j2 -->
{% extends ultra_base %}
{% block extra_js %}
<script src="somefile.js">
{% endblock %}
{% block page_js %} {% endblock %}
and
<-- grandchild.j2 -->
{% extends child %}
{% block content %}
<h2> Grandchild Content </h2>
{% endblock content %}
{% block page_js %}
<script src="grandchild.js"></script>
{% endblock page_js %}
The page_js block is never rendered. Is there some way to render it without changing ultra_base?
You could render page_js by putting the {% block page_js %} {% endblock %} inside the extra_js block in child.j2:
<-- child.j2 -->
{% extends ultra_base %}
{% block extra_js %}
<script src="somefile.js">
{% block page_js %}
{% endblock %}
{% endblock %}
The problem is that the page_js block in child.j2 is "in the middle of nowhere", it does not alter any block of the ulta_base.j2, so Jinja2 will not render anything from it. The solution is quite simple, you don't even need to define a new extra_js block, just use Jinja2's super() function:
ultra_base.j2 remains the same:
<!-- ultra_base.j2 -->
<head>
</head>
<body>
{% block content %}{% endblock %}
{% block extra_js %} {% endblock %}
</body>
the child.j2 template:
<!-- child.j2 -->
{% extends ultra_base %}
{% block extra_js %}
{{ super() }}
<script src="somefile.js"></script>
{% endblock %}
and the grandchildj2:
<!-- grandchild.j2 -->
{% extends child %}
{% block content %}
<h2> Grandchild Content </h2>
{% endblock content %}
{% block extra_js %}
{{ super() }}
<script src="grandchild.js"></script>
{% endblock extra_js %}
Jinja2 will take care of including block contents from the parent templates.

Django Admin Inline Change List

I can edit a parent child relationship using the TablularInline and StackedInline classes, however I would prefer to list the child relationships as a change list as there is a lot of information and the forms are too big. Is there an inline change list available in DJango admin or a way or creating one?
There's no such functionality built in, but I don't think it would be hard to create your own AdminInline subclass (and an accompanying template for it) that would do this. Just model it off TabularInline, but display fields' data directly instead of rendering form fields.
So I was actually able to achieve this with quite the hack. Django Admin needs some updates and InlineAnything would be one.
Download Library: https://github.com/smartlgt/django-fakeinline
class MyInlineTest(FakeInline):
def __init__(self, parent_model, admin_site):
super().__init__(parent_model, admin_site)
self.template = Template('')
self.admin_site = admin_site
def get_fields(self, request, obj=None):
dpaa = DisplayProductAccessAdmin(DisplayProductAccess, self.admin_site)
dpaa.change_list_template = 'test.html'
self.template = Template(dpaa.changelist_view(request, {}).rendered_content)
return FakeInline.get_fields(self, request, obj=obj)
Then in your test.html, take most of the contents of the change_list.html from Django. Since we're using Jazzmin let's go with that.
{% load i18n admin_urls static admin_list jazzmin %}
{% block extrastyle %}
<link rel="stylesheet" href="{% static 'vendor/select2/css/select2.min.css' %}">
{% if cl.formset or action_form %}
<script type="text/javascript" src="{% url 'admin:jsi18n' %}"></script>
{% endif %}
{{ media.css }}
{% if not actions_on_top and not actions_on_bottom %}
<style>
#changelist table thead th:first-child {width: inherit}
</style>
{% endif %}
{% endblock %}
{% block extrahead %}
{{ media.js }}
{% endblock %}
{% block content %}
<div class="col-12">
<div class="card card-primary card-outline">
<div class="card-header">
<h4 class="card-title">{{ title }}{% block pretitle %}{% endblock %}</h4>
<div class="card-tools form-inline">
{% block date_hierarchy %}{% if cl.date_hierarchy %}{% date_hierarchy cl %}{% endif %}{% endblock %}
{% block search %}
{% search_form cl %}
{% endblock %}
</div>
</div>
<div class="card-body">
<form id="changelist-form" method="post"{% if cl.formset and cl.formset.is_multipart %}enctype="multipart/form-data"{% endif %} novalidate>{% csrf_token %}
<div id="content-main">
{% if cl.formset and cl.formset.errors %}
<p class="errornote">
{% if cl.formset.total_error_count == 1 %}
{% trans "Please correct the error below." %}
{% else %}
{% trans "Please correct the errors below." %}
{% endif %}
</p>
{{ cl.formset.non_form_errors }}
{% endif %}
<div class="module{% if cl.has_filters %} filtered{% endif %}" id="changelist">
<div class="row">
<div class="col-12">
{% if cl.formset %}
<div>{{ cl.formset.management_form }}</div>
{% endif %}
{% block result_list %}
<div class="row">
<div class="col-12 col-sm-8">
{% if action_form and actions_on_top and cl.show_admin_actions %}
{% admin_actions %}
{% endif %}
</div>
<div class="col-12 col-sm-4">
{% block object-tools %}
{% block object-tools-items %}
{% change_list_object_tools %}
{% endblock %}
{% endblock %}
</div>
</div>
<hr/>
{% result_list cl %}
{% if action_form and actions_on_bottom and cl.show_admin_actions %}
<div class="row">
<div class="col-12">
{% admin_actions %}
</div>
</div>
{% endif %}
{% endblock %}
</div>
</div>
<div class="row">
{% block pagination %}{% pagination cl %}{% endblock %}
</div>
</div>
</div>
</form>
</div>
</div>
<br class="clear"/>
</div>
{% endblock %}
{% block extrajs %}
<script type="text/javascript" src="{% static 'vendor/select2/js/select2.min.js' %}"></script>
<script type="text/javascript" src="{% static 'jazzmin/js/change_list.js' %}"></script>
{% endblock %}

Categories