Quem já não precisou criar um menu no django admin? Muitas vezes fazemos de forma estática, tendo que atualizar a cada model ou app adicionados. Bom neste post irei mostrar como criar um menu totalmente dinâmico, montado de acordo com suas apps e com os direitos de cada usuário que irá utilizar o admin.
Suponho que você já tenha criado um projeto com o admin habilitado.
A primeira coisa a fazer é baixar o seguinte snippet:
http://djangosnippets.org/snippets/1921/
Depois de baixado, coloque-o em algum lugar da sua aplicação. Eu sempre crio um módulo chamado
snippets para guadar os snippets que uso em minhas aplicações.
Edite o
TEMPLATE_CONTEXT_PROCESSORS de sua aplicação no arquivo
settings.py. Deixe como abaixo:
TEMPLATE_CONTEXT_PROCESSORS = (
'django.core.context_processors.auth',
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.media',
'django.core.context_processors.request',
'snippets.1921.applist', #aponte para o local onde você salvou o arquivo 1921.py
)
Altere os templates base do admin. São eles
base.html e
base_site.html. Deixe-os como abaixo:
- base.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="{{ LANGUAGE_CODE }}" xml:lang="{{ LANGUAGE_CODE }}" {% if LANGUAGE_BIDI %}dir="rtl"{% endif %}>
<head>
<title>{% block title %}{% endblock %}</title>
<link rel="stylesheet" type="text/css" href="{% block stylesheet %}{% load adminmedia %}{% admin_media_prefix %}css/base.css{% endblock %}" />
{% block extrastyle %}{% endblock %}
<!--[if lte IE 7]><link rel="stylesheet" type="text/css" href="{% block stylesheet_ie %}{% load adminmedia %}{% admin_media_prefix %}css/ie.css{% endblock %}" /><![endif]-->
{% if LANGUAGE_BIDI %}<link rel="stylesheet" type="text/css" href="{% block stylesheet_rtl %}{% admin_media_prefix %}css/rtl.css{% endblock %}" />{% endif %}
<script type="text/javascript">window.__admin_media_prefix__ = "{% filter escapejs %}{% admin_media_prefix %}{% endfilter %}";</script>
{% block extrahead %}{% endblock %}
{% block blockbots %}<meta name="robots" content="NONE,NOARCHIVE" />{% endblock %}
</head>
{% load i18n %}
<body class="{% if is_popup %}popup {% endif %}{% block bodyclass %}{% endblock %}">
<!-- Container -->
<div id="container">
{% if not is_popup %}
<!-- Header -->
<div id="header">
<div id="branding">
{% block branding %}{% endblock %}
</div>
{% if user.is_active and user.is_staff %}
<div id="user-tools">
{% trans 'Welcome,' %}
<strong>{% filter force_escape %}{% firstof user.first_name user.username %}{% endfilter %}</strong>.
{% block userlinks %}
{% url django-admindocs-docroot as docsroot %}
{% if docsroot %}
<a href="{{ docsroot }}">{% trans 'Documentation' %}</a> /
{% endif %}
{% url admin:password_change as password_change_url %}
{% if password_change_url %}
<a href="{{ password_change_url }}">
{% else %}
<a href="{{ root_path }}password_change/">
{% endif %}
{% trans 'Change password' %}</a> /
{% url admin:logout as logout_url %}
{% if logout_url %}
<a href="{{ logout_url }}">
{% else %}
<a href="{{ root_path }}logout/">
{% endif %}
{% trans 'Log out' %}</a>
{% endblock %}
</div>
{% endif %}
{% block nav-global %}{% endblock %}
</div>
<!-- END Header -->
{% block navmenu %}Aqui ficará o menu{% endblock %}
{% block breadcrumbs %}<div class="breadcrumbs"><a href="/">{% trans 'Home' %}</a>{% if title %} › {{ title }}{% endif %}</div>{% endblock %}
{% endif %}
{% if messages %}
<ul class="messagelist">{% for message in messages %}<li>{{ message }}</li>{% endfor %}</ul>
{% endif %}
<!-- Content -->
<div id="content" class="{% block coltype %}colM{% endblock %}">
{% block pretitle %}{% endblock %}
{% block content_title %}{% if title %}<h1>{{ title }}</h1>{% endif %}{% endblock %}
{% block content %}
{% block object-tools %}{% endblock %}
{{ content }}
{% endblock %}
{% block sidebar %}{% endblock %}
<br class="clear" />
</div>
<!-- END Content -->
{% block footer %}<div id="footer"></div>{% endblock %}
</div>
<!-- END Container -->
</body>
</html>
- base_site.html
{% extends "admin/base.html" %}
{% load i18n %}
{% block extrastyle %}{% load adminmedia %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/custom_admin.css" />{% endblock %}
{% block title %}{{ title }} | {% trans 'Django site admin' %}{% endblock %}
{% block branding %}
<h1 id="site-name">{% trans 'Django administration' %}</h1>
{% endblock %}
{% block navmenu %}
{% if adm_app_list %}
<div style="background: #EEE;width: 100%">
<ul id="navmenu">
<li><a href="/admin/">{% trans "Home" %}</a></li>
{% for app in adm_app_list %}
<li><a href="{{ app.app_url }}">{% blocktrans with app.name as name %}{{ name }}{% endblocktrans %}</a>
<ul>
{% for model in app.models %}
{% if model.perms.change %}
<li><a href="{{ model.admin_url }}">{{ model.name }}</a></li>
{% else %}
<li>{{ model.name }}</li>
{% endif %}
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% endblock %}
{% block nav-global %}{% endblock %}
Observe que foi adicionado o arquivo de estilo
custom_admin.css. Esse arquivo servirá para inserir o layout do menu e atualizar o layout de componentes do admin, caso seja necessário. Veja o
custom_admin.css, com um exemplo de layout para o menu:
/* NAVMENU CSS
------------------- */
/* Root = Horizontal, Secondary = Vertical */
ul#navmenu {
margin: 0;
border: 0 none;
padding: 0;
width: 500px; /*For KHTML*/
list-style: none;
height: 24px;
}
ul#navmenu li {
margin: 0;
border: 0 none;
padding: 0;
float: left; /*For Gecko*/
display: inline;
list-style: none;
position: relative;
height: 24px;
}
ul#navmenu ul {
margin: 0;
border: 0 none;
padding: 0;
width: 160px;
list-style: none;
display: none;
position: absolute;
top: 24px;
left: 0;
z-index: 1;
}
ul#navmenu ul li {
float: none; /*For Gecko*/
display: block !important;
display: inline; /*For IE*/
}
/* Root Menu */
ul#navmenu a {
border: 1px solid #FFF;
border-right-color: #CCC;
border-bottom-color: #CCC;
padding: 0 6px;
float: none !important; /*For Opera*/
float: left; /*For IE*/
display: block;
background: #EEE;
color: #666;
font: bold 10px/22px Verdana, Arial, Helvetica, sans-serif;
text-decoration: none;
height: auto !important;
height: 100%; /*For IE*/
}
/* Root Menu Hover Persistence */
ul#navmenu a:hover,
ul#navmenu li:hover a,
ul#navmenu li.iehover a {
background: #CCC;
color: #FFF;
}
/* 2nd Menu */
ul#navmenu li:hover li a,
ul#navmenu li.iehover li a {
float: none;
background: #EEE;
color: #666;
}
/* 2nd Menu Hover Persistence */
ul#navmenu li:hover li a:hover,
ul#navmenu li:hover li:hover a,
ul#navmenu li.iehover li a:hover,
ul#navmenu li.iehover li.iehover a {
background: #CCC;
color: #FFF;
}
/* 3rd Menu */
ul#navmenu li:hover li:hover li a,
ul#navmenu li.iehover li.iehover li a {
background: #EEE;
color: #666;
}
/* 3rd Menu Hover Persistence */
ul#navmenu li:hover li:hover li a:hover,
ul#navmenu li:hover li:hover li:hover a,
ul#navmenu li.iehover li.iehover li a:hover,
ul#navmenu li.iehover li.iehover li.iehover a {
background: #CCC;
color: #FFF;
}
/* 4th Menu */
ul#navmenu li:hover li:hover li:hover li a,
ul#navmenu li.iehover li.iehover li.iehover li a {
background: #EEE;
color: #666;
}
/* 4th Menu Hover */
ul#navmenu li:hover li:hover li:hover li a:hover,
ul#navmenu li.iehover li.iehover li.iehover li a:hover {
background: #CCC;
color: #FFF;
}
ul#navmenu ul ul,
ul#navmenu ul ul ul {
display: none;
position: absolute;
top: 0;
left: 160px;
}
/* Do Not Move - Must Come Before display:block for Gecko */
ul#navmenu li:hover ul ul,
ul#navmenu li:hover ul ul ul,
ul#navmenu li.iehover ul ul,
ul#navmenu li.iehover ul ul ul {
display: none;
}
ul#navmenu li:hover ul,
ul#navmenu ul li:hover ul,
ul#navmenu ul ul li:hover ul,
ul#navmenu li.iehover ul,
ul#navmenu ul li.iehover ul,
ul#navmenu ul ul li.iehover ul {
display: block;
}
Se tudo estiver correto você já pode ver o seu menu no admin do Django.
Veja imagens do menu aplicado a um projeto:
Para melhor visualização do código veja projeto em:
https://github.com/dimasguilherme/Django-Admin-Menu