Created
July 11, 2013 22:08
-
-
Save glarrain/5979690 to your computer and use it in GitHub Desktop.
Django custom admin site. App name `custom_admin`
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{% load admin_static %}{% load url from future %}<!DOCTYPE html> | |
<html lang="{{ LANGUAGE_CODE|default:"en-us" }}" {% if LANGUAGE_BIDI %}dir="rtl"{% endif %}> | |
{% comment %} | |
This template is almost a copy (with indentation corrections and modifications listed below) of | |
'django/contrib/admin/templates/admin/base.html' and overrides it by living in directory | |
'/templates/admin/', as instructed in documentation: | |
"For those templates that cannot be overridden in this way, you may still override them for | |
your entire project. Just place the new version in your templates/admin directory." | |
https://docs.djangoproject.com/en/1.4/ref/contrib/admin/#overriding-admin-templates | |
Modifications: | |
* removed ` and user.is_staff` from "if" around div "user-tools" | |
* added `{% if show_user_links %}` around block "userlinks" | |
* moved the logout link out and below that block | |
{% endcomment %} | |
<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 lte IE 7]><link rel="stylesheet" type="text/css" href="{% block stylesheet_ie %}{% static "admin/css/ie.css" %}{% endblock %}" /><![endif]--> | |
{% if LANGUAGE_BIDI %}<link rel="stylesheet" type="text/css" href="{% block stylesheet_rtl %}{% static "admin/css/rtl.css" %}{% endblock %}" />{% endif %} | |
<script type="text/javascript">window.__admin_media_prefix__ = "{% filter escapejs %}{% static "admin/" %}{% 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 %} | |
<h1 id="site-name"> | |
<img src="{% static 'images/lookup-index-logo-small.png' %}" | |
alt="LookUP" width="200" height="82"> | |
</h1> | |
{% endblock %} | |
</div> | |
{% if user.is_active %} | |
<div id="user-tools"> | |
{% if show_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 %} | |
<a href="{% url 'admin:password_change' %}">{% trans 'Change password' %}</a> / | |
{% endblock %} | |
{% endif %} | |
<a href="{% url 'admin:logout' %}">{% trans 'Log out' %}</a> | |
</div> | |
{% endif %} | |
{% block nav-global %}{% endblock %} | |
</div> | |
<!-- END Header --> | |
{% block breadcrumbs %} | |
<div class="breadcrumbs"> | |
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a> | |
{% if title %} › {{ title }}{% endif %} | |
</div> | |
{% endblock %} | |
{% endif %} | |
{% block messages %} | |
{% if messages %} | |
<ul class="messagelist"> | |
{% for message in messages %} | |
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li> | |
{% endfor %} | |
</ul> | |
{% endif %} | |
{% endblock messages %} | |
<!-- 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> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{% extends "admin/base.html" %} | |
{% load i18n %} | |
{% comment %} | |
This template is based on 'django/contrib/admin/templates/admin/base.html' and overrides it by | |
living in directory '/templates/admin/', as instructed in documentation: | |
"For those templates that cannot be overridden in this way, you may still override them for | |
your entire project. Just place the new version in your templates/admin directory." | |
https://docs.djangoproject.com/en/1.4/ref/contrib/admin/#overriding-admin-templates | |
{% endcomment %} | |
{% block title %} | |
{{ title }} | {% if site %}{{ site.name }}{% else %}{% trans 'Django site admin' %}{% endif %} | |
{% endblock %} | |
{% block branding %} | |
{{ block.super }} | |
{% endblock %} | |
{% block nav-global %}{% endblock %} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import django.contrib.admin.forms | |
import django.contrib.auth.forms | |
class AdminCustomAuthForm(django.contrib.admin.forms.AdminAuthenticationForm): | |
"""Custom admin.forms.AdminAuthenticationForm that "replaces" | |
:meth:`clean` with the one from its superclass | |
auth.forms.AuthenticationForm. | |
The purpose is to remove references to ``user.is_staff``. | |
""" | |
def clean(self): | |
return django.contrib.auth.forms.AuthenticationForm.clean(self) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Module equivalent to :mod:`django.contrib.admin.options`, where | |
:class:`ModelAdmin` lives. | |
""" | |
import django.contrib.admin.options | |
class CustomModelAdmin(django.contrib.admin.options.ModelAdmin): | |
"""Custom ModelAdmin that overrides :meth:`get_actions`.""" | |
def get_actions(self, request): | |
"""Remove action "delete" if :meth:`has_delete_permission` is False | |
for ``obj=None``. | |
``obj=None`` means *any* object of the given model. Thus, if the | |
user can't delete any of the objects, remove the delete action. | |
""" | |
# the hardcoded string is from AdminSite's constructor | |
delete_action_key = 'delete_selected' | |
actions = super(CustomModelAdmin, self).get_actions(request) | |
if not self.has_delete_permission(request, obj=None): | |
actions.pop(delete_action_key, None) # "safe" pop | |
return actions |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import django.contrib.admin | |
from . import forms | |
class CustomAdminSite(django.contrib.admin.AdminSite): | |
"""Custom AdminSite that: | |
* optionally removes the check for user attribute ``is_staff`` | |
* checks for a given set of permissions | |
* overrides ``index_template``, ``login_template`` | |
* adds :attr:`title` | |
* overrides :meth:`index` to use :attr:`title` and :attr:`show_user_tools` | |
Partly inspired in | |
* http://www.tryolabs.com/Blog/2012/06/18/django-administration-interface-non-staff-users/ | |
* https://docs.djangoproject.com/en/1.4/ref/contrib/admin/ | |
* http://stackoverflow.com/a/11225984/556413 | |
""" | |
login_form = forms.AdminCustomAuthForm | |
def __init__(self, name='admin', app_name='admin', | |
title=None, check_user_is_staff=False, | |
required_permissions=None, show_user_tools=True, **kwargs): | |
"""Constructor | |
:param title: of the admin site | |
:param check_user_is_staff: whether to verify that | |
``user.is_staff`` is True | |
:param required_permissions: user permissions to require for viewing | |
pages in this site | |
:type required_permissions: iterable of strings, | |
**not** permission objects e.g. ``('app.permission_name', )`` | |
:param show_user_tools: whether to display links for user e.g. | |
change password, close session | |
""" | |
super(CustomAdminSite, self).__init__(name, app_name, **kwargs) | |
self.title = title | |
self.check_user_is_staff = check_user_is_staff | |
self.required_permissions = required_permissions | |
self.show_user_tools = show_user_tools | |
def has_permission(self, request): | |
"""Return whether ``request`` is allowed to view pages in this site. | |
True if user: | |
* is active, and | |
* is staff (if :attr:`check_user_is_staff` is True), and | |
* has all the permissions in :attr:`required_permissions` | |
Based in :meth:`AdminSite.has_permission`, optionally removes the check | |
of ``request.user``'s attribute ``is_staff``. | |
""" | |
if self.check_user_is_staff: | |
if not request.user.is_staff: | |
return False | |
if self.required_permissions: | |
if not request.user.has_perms(self.required_permissions): | |
return False | |
return request.user.is_active | |
def index(self, request, extra_context=None, **kwargs): | |
"""Override to set ``title`` in ``extra_context``.""" | |
# TODO: should we add the decorator "never_cache" here too? | |
if self.title: | |
ctx = {'title': self.title, 'show_user_tools': self.show_user_tools} | |
if extra_context is None: | |
extra_context = ctx | |
else: | |
extra_context.update(ctx) | |
return super(CustomAdminSite, self).index(request, extra_context, | |
**kwargs) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment