Removed admin support (no longer used or maintained).

This commit is contained in:
Chris Church 2014-03-28 22:04:26 -04:00
parent 7754f475ad
commit 352197c5d2
7 changed files with 5 additions and 843 deletions

View File

@ -1,391 +0,0 @@
# Copyright (c) 2014 AnsibleWorks, Inc.
# All Rights Reserved.
# Django admin isn't officially supported!
# Python
import json
import urllib
# Django
from django.conf.urls import *
from django.contrib import admin
from django.contrib.admin.util import unquote
from django.contrib import messages
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.utils.timezone import now
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import User
from django.contrib.auth.admin import UserAdmin
# AWX
from awx.lib.compat import format_html
from awx.main.models import *
from awx.main.forms import *
class UserAdmin(UserAdmin):
fieldsets = (
(None, {'fields': ('username', 'password')}),
(_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}),
(_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser')}),
(_('Important dates'), {'fields': ('last_login', 'date_joined')}),
)
readonly_fields = ('last_login', 'date_joined')
list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff')
list_filter = ('is_staff', 'is_superuser', 'is_active', 'groups')
search_fields = ('username', 'first_name', 'last_name', 'email')
ordering = ('username',)
try:
admin.site.unregister(User)
except admin.site.NotRegistered:
pass
admin.site.register(User, UserAdmin)
# FIXME: Hide auth.Group admin
class BaseModelAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
# Automatically set created_by when saved from the admin.
# FIXME: Doesn't handle inline model instances yet.
if hasattr(obj, 'created_by') and obj.created_by is None:
obj.created_by = request.user
return super(BaseModelAdmin, self).save_model(request, obj, form, change)
class OrganizationAdmin(BaseModelAdmin):
list_display = ('name', 'description', 'active')
list_filter = ('active', 'tags')
fieldsets = (
(None, {'fields': (('name', 'active'), 'description',)}),
(_('Members'), {'fields': ('users', 'admins',)}),
(_('Projects'), {'fields': ('projects',)}),
(_('Tags'), {'fields': ('tags',)}),
(_('Audit'), {'fields': ('created', 'created_by',)}),
)
readonly_fields = ('active', 'created', 'created_by')
filter_horizontal = ('users', 'admins', 'projects')
class InventoryHostInline(admin.StackedInline):
model = Host
extra = 0
fields = ('name', 'description', 'active', 'tags')
readonly_fields = ('active',)
class InventoryGroupInline(admin.StackedInline):
model = Group
extra = 0
fields = ('name', 'description', 'active', 'parents', 'hosts', 'tags')
readonly_fields = ('active',)
filter_horizontal = ('parents', 'hosts')
class InventoryAdmin(BaseModelAdmin):
list_display = ('name', 'organization', 'description', 'active')
list_filter = ('organization', 'active')
form = InventoryAdminForm
fieldsets = (
(None, {'fields': (('name', 'active'), 'organization', 'description',
'variables')}),
(_('Tags'), {'fields': ('tags',)}),
(_('Audit'), {'fields': ('created', 'created_by',)}),
)
readonly_fields = ('active', 'created', 'created_by')
inlines = [InventoryHostInline, InventoryGroupInline]
class JobHostSummaryInline(admin.TabularInline):
model = JobHostSummary
extra = 0
can_delete = False
def has_add_permission(self, request):
return False
class JobEventInline(admin.StackedInline):
model = JobEvent
extra = 0
can_delete = False
def has_add_permission(self, request):
return False
def get_event_data_display(self, obj):
return format_html('<pre class="json-display">{0}</pre>',
json.dumps(obj.event_data, indent=4))
get_event_data_display.short_description = _('Event data')
get_event_data_display.allow_tags = True
class JobHostSummaryInlineForHost(JobHostSummaryInline):
fields = ('job', 'changed', 'dark', 'failures', 'ok', 'processed',
'skipped', 'failed')
readonly_fields = ('job', 'changed', 'dark', 'failures', 'ok', 'processed',
'skipped', 'failed')
class JobEventInlineForHost(JobEventInline):
fields = ('job', 'created', 'event', 'get_event_data_display')
readonly_fields = ('job', 'created', 'event', 'get_event_data_display')
class HostAdmin(BaseModelAdmin):
list_display = ('name', 'inventory', 'description', 'active')
list_filter = ('inventory', 'active')
form = HostAdminForm
fieldsets = (
(None, {'fields': (('name', 'active'), 'inventory', 'description',
'variables',
)}),
(_('Tags'), {'fields': ('tags',)}),
(_('Audit'), {'fields': ('created', 'created_by',)}),
)
readonly_fields = ('active', 'created', 'created_by')
# FIXME: Edit reverse of many to many for groups.
inlines = [JobHostSummaryInlineForHost, JobEventInlineForHost]
class GroupAdmin(BaseModelAdmin):
list_display = ('name', 'description', 'active')
form = GroupAdminForm
fieldsets = (
(None, {'fields': (('name', 'active'), 'inventory', 'description',
'parents', 'variables')}),
(_('Tags'), {'fields': ('tags',)}),
(_('Audit'), {'fields': ('created', 'created_by',)}),
)
readonly_fields = ('active', 'created', 'created_by')
filter_horizontal = ('parents', 'hosts')
class CredentialAdmin(BaseModelAdmin):
fieldsets = (
(None, {'fields': (('name', 'active'), ('user', 'team'), 'description')}),
(_('Auth Info'), {'fields': (('username', 'password'),
'ssh_key_data', 'ssh_key_unlock',
('sudo_username', 'sudo_password'))}),
(_('Tags'), {'fields': ('tags',)}),
(_('Audit'), {'fields': ('created', 'created_by',)}),
)
readonly_fields = ('active', 'created', 'created_by')
class TeamAdmin(BaseModelAdmin):
list_display = ('name', 'description', 'active')
filter_horizontal = ('projects', 'users')
class ProjectUpdateInline(admin.StackedInline):
model = ProjectUpdate
extra = 0
can_delete = True
fields = ('created', 'status', 'result_stdout')
readonly_fields = ('created', 'status', 'result_stdout')
def has_add_permission(self, request):
return False
class ProjectAdmin(BaseModelAdmin):
list_display = ('name', 'description', 'active')
fieldsets = (
(None, {'fields': (('name', 'active'), 'description', 'local_path',
'get_playbooks_display')}),
(_('SCM'), {'fields': ('scm_type', 'scm_url', 'scm_branch')}),
(_('Tags'), {'fields': ('tags',)}),
(_('Audit'), {'fields': ('created', 'created_by',)}),
)
readonly_fields = ('active', 'created', 'created_by',
'get_playbooks_display')
form = ProjectAdminForm
inlines = [ProjectUpdateInline]
def get_playbooks_display(self, obj):
return '<br/>'.join([format_html('{0}', x) for x in
obj.playbooks])
get_playbooks_display.short_description = _('Playbooks')
get_playbooks_display.allow_tags = True
class PermissionAdmin(BaseModelAdmin):
list_display = ('name', 'description', 'active')
class JobTemplateAdmin(BaseModelAdmin):
list_display = ('name', 'description', 'active', 'get_create_link_display',
'get_jobs_link_display')
fieldsets = (
(None, {'fields': ('name', 'active', 'description',
'get_create_link_display', 'get_jobs_link_display')}),
(_('Job Parameters'), {'fields': ('inventory', 'project', 'playbook',
'credential', 'job_type')}),
(_('More Options'), {'fields': ('forks', 'limit', 'verbosity',
'extra_vars', 'job_tags', 'host_config_key'),
'classes': ('collapse',)}),
(_('Tags'), {'fields': ('tags',)}),
(_('Audit'), {'fields': ('created', 'created_by',)}),
)
readonly_fields = ('active', 'created', 'created_by',
'get_create_link_display', 'get_jobs_link_display')
form = JobTemplateAdminForm
def get_create_link_display(self, obj):
if not obj or not obj.pk:
return ''
info = Job._meta.app_label, Job._meta.module_name
create_url = reverse('admin:%s_%s_add' % info,
current_app=self.admin_site.name)
create_opts = {
'job_template': obj.pk,
'job_type': obj.job_type,
'description': obj.description,
'name': '%s %s' % (obj.name, now().isoformat()),
}
if obj.inventory:
create_opts['inventory'] = obj.inventory.pk
if obj.project:
create_opts['project'] = obj.project.pk
if obj.playbook:
create_opts['playbook'] = obj.playbook
if obj.credential:
create_opts['credential'] = obj.credential.pk
if obj.forks:
create_opts['forks'] = obj.forks
if obj.limit:
create_opts['limit'] = obj.limit
if obj.verbosity:
create_opts['verbosity'] = obj.verbosity
if obj.extra_vars:
create_opts['extra_vars'] = obj.extra_vars
if obj.job_tags:
create_opts['job_tags'] = obj.job_tags
create_url += '?%s' % urllib.urlencode(create_opts)
return format_html('<a href="{0}">{1}</a>', create_url, 'Create Job')
get_create_link_display.short_description = _('Create Job')
get_create_link_display.allow_tags = True
def get_jobs_link_display(self, obj):
if not obj or not obj.pk:
return ''
info = Job._meta.app_label, Job._meta.module_name
jobs_url = reverse('admin:%s_%s_changelist' % info,
current_app=self.admin_site.name)
jobs_url += '?job_template__id__exact=%d' % obj.pk
return format_html('<a href="{0}">{1}</a>', jobs_url, 'View Jobs')
get_jobs_link_display.short_description = _('View Jobs')
get_jobs_link_display.allow_tags = True
class JobHostSummaryInlineForJob(JobHostSummaryInline):
fields = ('host', 'changed', 'dark', 'failures', 'ok', 'processed',
'skipped', 'failed')
readonly_fields = ('host', 'changed', 'dark', 'failures', 'ok',
'processed', 'skipped', 'failed')
class JobEventInlineForJob(JobEventInline):
fields = ('created', 'event', 'get_event_data_display', 'failed', 'host')
readonly_fields = ('created', 'event', 'get_event_data_display', 'failed',
'host')
class JobAdmin(BaseModelAdmin):
list_display = ('__unicode__', 'job_template', 'project', 'playbook', 'status')
list_filter = ('status',)
fieldsets = (
(None, {'fields': ('job_template', 'description')}),
(_('Job Parameters'), {'fields': ('inventory', 'project', 'playbook',
'credential', 'job_type')}),
(_('More Options'), {'fields': ('forks', 'limit', 'verbosity',
'extra_vars', 'job_tags'),
'classes': ('collapse',)}),
(_('Start Job'), {'fields': ('start_job', 'ssh_password',
'sudo_password', 'ssh_key_unlock')}),
(_('Tags'), {'fields': ('tags',)}),
(_('Audit'), {'fields': ('created', 'created_by',)}),
(_('Job Status'), {'fields': (('status', 'failed', 'cancel_job'),
'get_result_stdout_display',
'get_result_traceback_display',
'celery_task_id')}),
)
readonly_fields = ('status', 'failed', 'get_job_template_display',
'get_result_stdout_display',
'get_result_traceback_display', 'celery_task_id',
'created', 'created_by')
form = JobAdminForm
inlines = [JobHostSummaryInlineForJob, JobEventInlineForJob]
def get_readonly_fields(self, request, obj=None):
ro_fields = list(super(JobAdmin, self).get_readonly_fields(request, obj))
if obj and obj.pk and obj.status != 'new':
ro_fields.extend(['description', 'job_template',
'inventory', 'project', 'playbook', 'credential',
'job_type', 'forks', 'limit',
'verbosity', 'extra_vars', 'job_tags'])
return ro_fields
def get_fieldsets(self, request, obj=None):
fsets = list(super(JobAdmin, self).get_fieldsets(request, obj))
if not obj or not obj.pk or obj.status == 'new':
fsets = [fs for fs in fsets if
'created' not in fs[1]['fields'] and
'celery_task_id' not in fs[1]['fields']]
if not obj or (obj and obj.pk and not obj.can_start):
fsets = [fs for fs in fsets if 'start_job' not in fs[1]['fields']]
if not obj or (obj and obj.pk and not obj.can_cancel):
for fs in fsets:
if 'celery_task_id' in fs[1]['fields']:
fs[1]['fields'] = ('status', 'get_result_stdout_display',
'get_result_traceback_display',
'celery_task_id')
return fsets
def get_inline_instances(self, request, obj=None):
if obj and obj.pk and obj.status != 'new':
return super(JobAdmin, self).get_inline_instances(request, obj)
else:
return []
def get_job_template_display(self, obj):
if obj.job_template:
info = JobTemplate._meta.app_label, JobTemplate._meta.module_name
job_template_url = reverse('admin:%s_%s_change' % info,
args=(obj.job_template.pk,),
current_app=self.admin_site.name)
return format_html('<a href="{0}">{1}</a>', job_template_url,
obj.job_template)
else:
return _('(None)')
get_job_template_display.short_description = _('Job template')
get_job_template_display.allow_tags = True
def get_result_stdout_display(self, obj):
return format_html('<pre class="result-display">{0}</pre>',
obj.result_stdout or ' ')
get_result_stdout_display.short_description = _('Stdout')
get_result_stdout_display.allow_tags = True
def get_result_traceback_display(self, obj):
return format_html('<pre class="result-display">{0}</pre>',
obj.result_traceback or ' ')
get_result_traceback_display.short_description = _('Traceback')
get_result_traceback_display.allow_tags = True
admin.site.register(Organization, OrganizationAdmin)
admin.site.register(Inventory, InventoryAdmin)
#admin.site.register(Tag, TagAdmin)
#admin.site.register(AuditTrail, AuditTrailAdmin)
admin.site.register(Host, HostAdmin)
admin.site.register(Group, GroupAdmin)
#admin.site.register(VariableData, VariableDataAdmin)
admin.site.register(Team, TeamAdmin)
admin.site.register(Project, ProjectAdmin)
admin.site.register(Credential, CredentialAdmin)
admin.site.register(JobTemplate, JobTemplateAdmin)
admin.site.register(Job, JobAdmin)

View File

@ -1,159 +0,0 @@
# Copyright (c) 2014 AnsibleWorks, Inc.
# All Rights Reserved.
# Python
import json
# PyYAML
import yaml
# Django
from django import forms
from django.utils.translation import ugettext_lazy as _
# AWX
from awx.main.models import *
EMPTY_CHOICE = ('', '---------')
class PlaybookOption(object):
def __init__(self, project, playbook):
self.project, self.playbook = project, playbook
def __unicode__(self):
return self.playbook
class PlaybookSelect(forms.Select):
'''Custom select widget for playbooks related to a project.'''
def render_option(self, selected_choices, option_value, obj):
opt = super(PlaybookSelect, self).render_option(selected_choices,
option_value,
unicode(obj))
# Add a class with the project ID so JS can filter the options.
if hasattr(obj, 'project'):
opt = opt.replace('">', '" class="project-%s">' % obj.project.pk)
return opt
class ModelFormWithVariables(forms.ModelForm):
'''Custom model form to validate variable data.'''
def clean_variables(self):
value = self.cleaned_data.get('variables', '')
try:
json.loads(value.strip() or '{}')
except ValueError:
try:
yaml.safe_load(value)
except yaml.YAMLError:
raise forms.ValidationError('Must be valid JSON or YAML')
return value
class InventoryAdminForm(ModelFormWithVariables):
'''Custom model form for Inventory.'''
class Meta:
model = Inventory
class HostAdminForm(ModelFormWithVariables):
'''Custom model form for Hosts.'''
class Meta:
model = Host
class GroupAdminForm(ModelFormWithVariables):
'''Custom model form for Groups.'''
class Meta:
model = Group
class ProjectAdminForm(forms.ModelForm):
'''Custom admin form for Projects.'''
local_path = forms.ChoiceField(choices=[])
class Meta:
model = Project
def __init__(self, *args, **kwargs):
super(ProjectAdminForm, self).__init__(*args, **kwargs)
self.fields['local_path'].choices = [(x, x) for x in Project.get_local_path_choices()]
class JobTemplateAdminForm(forms.ModelForm):
'''Custom admin form for creating/editing JobTemplates.'''
playbook = forms.ChoiceField(choices=[EMPTY_CHOICE], widget=PlaybookSelect)
class Meta:
model = JobTemplate
def __init__(self, *args, **kwargs):
super(JobTemplateAdminForm, self).__init__(*args, **kwargs)
playbook_choices = []
for project in Project.objects.all():
for playbook in project.playbooks:
playbook_choices.append((playbook,
PlaybookOption(project, playbook)))
self.fields['playbook'].choices = [EMPTY_CHOICE] + playbook_choices
class JobAdminForm(JobTemplateAdminForm):
'''Custom admin form for creating Jobs.'''
start_job = forms.BooleanField(initial=False, required=False)
ssh_password = forms.CharField(label=_('SSH password'), required=False)
sudo_password = forms.CharField(required=False)
ssh_key_unlock = forms.CharField(label=_('SSH key passphrase'),
required=False)
cancel_job = forms.BooleanField(initial=False, required=False)
class Meta:
model = Job
def __init__(self, *args, **kwargs):
super(JobAdminForm, self).__init__(*args, **kwargs)
if self.instance.pk and self.instance.status != 'new':
self.fields.pop('playbook', None)
if (not self.data or self.data.get('start_job', '')) and \
self.instance.credential and self.instance.can_start:
for field in self.instance.get_passwords_needed_to_start():
if field not in self.fields:
continue
self.fields[field].required = True
def clean_start_job(self):
return self.cleaned_data.get('start_job', False)
def clean_cancel_job(self):
return self.cleaned_data.get('cancel_job', False)
def clean(self):
if self.instance.credential and self.instance.can_start:
for field in self.instance.get_passwords_needed_to_start():
if field in self.fields:
self.fields[field].required = True
return super(JobAdminForm, self).clean()
def save(self, commit=True):
instance = super(JobAdminForm, self).save(commit)
save_m2m = getattr(self, 'save_m2m', lambda: None)
should_start = bool(self.cleaned_data.get('start_job', '') and
instance.can_start)
start_opts = {}
for field in ('ssh_password', 'sudo_password', 'ssh_key_unlock'):
value = self.cleaned_data.get(field, '')
if value:
start_opts[field] = value
should_cancel = bool(self.cleaned_data.get('cancel_job', '') and
instance.can_cancel)
def new_save_m2m():
save_m2m()
if should_start:
instance.start(**start_opts)
if should_cancel:
instance.cancel()
if commit:
new_save_m2m()
else:
self.save_m2m = new_save_m2m
return instance

View File

@ -11,14 +11,11 @@ def handle_error(request, status=404, **kwargs):
# FIXME: Should attempt to check HTTP Accept request header and return
# plain JSON response instead of HTML (maybe only for /api/*).
context = kwargs
if 'django.contrib.admin' in settings.INSTALLED_APPS and request.path.startswith('/admin/'):
template_name = 'admin/error.html'
else:
# Return enough context to popuplate the base API template.
description = u'<pre class="err">%s</pre>' % context.get('content', '')
context['description'] = mark_safe(description)
context['content'] = ''
template_name = 'error.html'
# Return enough context to popuplate the base API template.
description = u'<pre class="err">%s</pre>' % context.get('content', '')
context['description'] = mark_safe(description)
context['content'] = ''
template_name = 'error.html'
return render(request, template_name, context, status=status)
def handle_403(request):

View File

@ -140,8 +140,6 @@ INSTALLED_APPS = (
'awx.main',
'awx.api',
'awx.ui',
# Django admin is disabled and not supported by default.
#'django.contrib.admin',
)
INTERNAL_IPS = ('127.0.0.1',)

View File

@ -1,251 +0,0 @@
{# Admin site customizations. #}
{% extends "admin/base.html" %}
{% load i18n %}
{% block title %}{{ title }} | {% trans 'AWX Admin' %}{% endblock %}
{% block extrastyle %}
{{ block.super }}
<link href="{{ STATIC_URL }}img/favicon.ico" rel="shortcut icon" />
<style type="text/css">
/* Heading and button background colors. */
#header
{
background: #171717 !important;
}
.module h2,
#content-related .module h2,
.module caption,
.inline-group h2,
.button.default
{
background: #171717 !important;
}
input[type="submit"].default,
.submit-row input.default
{
background: #51a351 !important;
}
body
{
background-color: #f5f5f5;
}
body h1, body h2, body h3 {
color: #333;
}
/* Heading and button foreground colors. */
#branding h1
{
color: white !important;
margin: 0;
padding-top: 4px;
text-transform: uppercase;
font-weight: normal;
}
#branding h1 img {
height: 48px;
width: auto;
margin: -10px 8px -6px -2px;
}
#user-tools {
padding-top: 1em;
}
.module h2,
.module h2 a,
#content-related .module h2,
.module caption,
.inline-group h2,
a.section,
a.section:link,
a.section:visited,
a.section:hover,
.button.default,
input[type="submit"].default,
.submit-row input.default
{
color: white !important;
}
/* Link color. */
a,
a:link,
a:visited,
#changelist-filter a:hover,
a:hover
{
color: #2773ae;
}
/* Button border color. */
.selector h2
{
border-color: #171717 !important;
}
body .button.default,
body input[type="submit"].default,
body .submit-row input.default
{
border: 1px solid #51a351;
border-color: #7c7 #383 #383 #7c7;
}
#header {
color: #ddd;
border-bottom: none;
}
#header a:hover {
color: #2078be;
text-decoration: none;
}
/* Object Tools */
body .object-tools li {
background: #888;
border-radius: 8px;
}
body .object-tools li:hover {
background: #aaa;
}
body .object-tools a:link,
body .object-tools a:visited,
body .object-tools a:hover,
body .object-tools li:hover a {
background: transparent;
text-decoration: none;
}
body .object-tools a.viewsitelink,
body .object-tools a.golink,
body .object-tools a.addlink {
background: transparent;
padding-right: 10px;
}
body .object-tools a.viewsitelink:hover,
body .object-tools a.golink:hover,
body .object-tools a.addlink:hover {
background: transparent;
}
body .object-tools a.viewsitelink:after,
body .object-tools a.golink:after {
content: " \27a1";
}
body .object-tools a.addlink:after {
content: " +";
}
a:hover,
a.section:hover
{
text-decoration: underline;
}
tr.row1 {
background-color: #f5f5f5;
}
ul.messagelist li {
background-color: #ccddee;
}
.errornote {
border-color: #b22222 !important;
color: #b22222 !important;
background-color: #fdc !important;
}
.errorlist li {
border-color: #b22222 !important;
background-color: #d24242 !important;
}
.errors {
background-color: #fdc !important;
}
.errors input,
.errors select,
.errors textarea {
border: 1px solid #b22222 !important;
}
pre.json-display, pre.result-display {
display: inline-block;
margin: 0;
padding: 0;
font-size: 0.9em;
}
pre.result-display {
width: 75%;
border: 1px solid #ccc;
background: #444;
color: #eee;
max-height: 300px;
overflow: auto;
}
#job_host_summaries-group table td.original p {
display: none
}
#job_host_summaries-group table tr.has_original td {
padding-top: 5px;
}
</style>
{% endblock %}
{% block extrahead %}
{{ block.super }}
{% endblock %}
{% block blockbots %}
{{ block.super }}
<script type="text/javascript">
var django = django || {};
if (django.jQuery) {
(function($) {
window.refreshJobStatus = function() {
var status = $('.field-status p').text();
if (status == 'Running' || status == 'Pending') {
var url = '{{ request.path }}';
$.get(url, function(data) {
var selectors = [
'.form-row.field-status',
'.field-get_result_stdout_display pre',
'.field-get_result_stderr_display pre',
'.field-get_result_traceback_display pre',
'.field-get_result_stdout_display pre',
'#job_host_summaries-group',
'#job_events-group',
]
$.each(selectors, function(index, selector) {
$(selector).html($(data).find(selector).html());
});
setTimeout('window.refreshJobStatus()', 5000);
});
}
}
// Update playbook list based on project selected.
function onProjectChange() {
var project_pk = $('select[name="project"]').val() || 0;
$('select[name="playbook"] span option').unwrap();
$('select[name="playbook"] option:not(.project-' + project_pk + '):not([value=""])').wrap('<span/>');
}
$(function() {
$('select[name="project"]').each(onProjectChange).change(onProjectChange);
})
setTimeout('window.refreshJobStatus()', 2000);
})(django.jQuery);
}
</script>
{% endblock %}
{% block branding %}
<h1 id="site-name"><img class="logo" src="{{ STATIC_URL }}img/logo.png">{% block branding_title %}{% trans 'AWX Admin' %}{% endblock %}</h1>
{% endblock %}
{% block userlinks %}
{{ block.super }}
{% endblock %}
{% block nav-global %}
{% if user.is_active and user.is_staff and not is_popup %}
{# Placeholder for version/hostname info. #}
{% endif %}
{{ block.super }}
{% endblock %}
{% block content_title %}
{{ block.super }}
{% endblock %}

View File

@ -1,20 +0,0 @@
{% extends "admin/base_site.html" %}
{% load i18n %}
{% block title %}{{ name }}{% endblock %}
{% block nav-global %}{% endblock %}
{% block content_title %}{% endblock %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url "admin:index" %}">{% trans "Home" %}</a> &rsaquo;
{{ name }}
</div>
{% endblock %}
{% block content %}
<h1 style="margin-bottom: 0.7em;">{{ name }}</h1>
<p>{{ content }}</p>
{% endblock %}

View File

@ -18,15 +18,3 @@ urlpatterns += patterns('awx.main.views',
url(r'^404.html$', 'handle_404'),
url(r'^500.html$', 'handle_500'),
)
if 'django.contrib.admin' in settings.INSTALLED_APPS:
from django.contrib import admin
admin.autodiscover()
urlpatterns += patterns('',
url(r'^admin/', include(admin.site.urls)),
)
urlpatterns += patterns('awx.main.views',
url(r'^admin/403.html$', 'handle_403'),
url(r'^admin/404.html$', 'handle_404'),
url(r'^admin/500.html$', 'handle_500'),
)