Skip to content

Commit

Permalink
Moved the admin CBVs into logically-named modules.
Browse files Browse the repository at this point in the history
  • Loading branch information
jphalip committed May 27, 2012
1 parent 808e9ad commit 27f8d4b
Show file tree
Hide file tree
Showing 12 changed files with 643 additions and 629 deletions.
4 changes: 2 additions & 2 deletions django/contrib/admin/filters.py
Expand Up @@ -186,7 +186,7 @@ def expected_parameters(self):
return [self.lookup_kwarg, self.lookup_kwarg_isnull]

def choices(self, cl):
from django.contrib.admin.views.main import EMPTY_CHANGELIST_VALUE
from django.contrib.admin.views.list import EMPTY_CHANGELIST_VALUE
yield {
'selected': self.lookup_val is None and not self.lookup_val_isnull,
'query_string': cl.get_query_string({},
Expand Down Expand Up @@ -368,7 +368,7 @@ def expected_parameters(self):
return [self.lookup_kwarg, self.lookup_kwarg_isnull]

def choices(self, cl):
from django.contrib.admin.views.main import EMPTY_CHANGELIST_VALUE
from django.contrib.admin.views.list import EMPTY_CHANGELIST_VALUE
yield {
'selected': (self.lookup_val is None
and self.lookup_val_isnull is None),
Expand Down
2 changes: 1 addition & 1 deletion django/contrib/admin/helpers.py
Expand Up @@ -169,7 +169,7 @@ def label_tag(self):

def contents(self):
from django.contrib.admin.templatetags.admin_list import _boolean_icon
from django.contrib.admin.views.main import EMPTY_CHANGELIST_VALUE
from django.contrib.admin.views.list import EMPTY_CHANGELIST_VALUE
field, obj, model_admin = self.field['field'], self.form.instance, self.model_admin
try:
f, attr, value = lookup_field(field, obj, model_admin)
Expand Down
12 changes: 6 additions & 6 deletions django/contrib/admin/options.py
Expand Up @@ -7,8 +7,8 @@
from django.contrib.admin import widgets, helpers
from django.contrib.admin.util import flatten_fieldsets, model_format_dict
from django.contrib.admin.templatetags.admin_static import static
from django.contrib.admin.views.cbv import (AdminChangeView, AdminAddView,
AdminDeleteView, ChangeListView, HistoryView)
from django.contrib.admin.views import (AdminChangeView, AdminAddView,
AdminDeleteView, AdminChangeListView, AdminHistoryView)
from django.contrib import messages
from django.views.decorators.csrf import csrf_protect
from django.core.exceptions import ValidationError
Expand Down Expand Up @@ -461,7 +461,7 @@ def get_changelist(self, request, **kwargs):
"""
Returns the ChangeList class for use on the changelist page.
"""
from django.contrib.admin.views.main import ChangeList
from django.contrib.admin.views.list import ChangeList
return ChangeList

def get_object(self, request, object_id, queryset=None):
Expand Down Expand Up @@ -570,7 +570,7 @@ def get_actions(self, request):
"""
# If self.actions is explicitally set to None that means that we don't
# want *any* actions enabled on this page.
from django.contrib.admin.views.main import IS_POPUP_VAR
from django.contrib.admin.views.list import IS_POPUP_VAR
if self.actions is None or IS_POPUP_VAR in request.GET:
return SortedDict()

Expand Down Expand Up @@ -943,7 +943,7 @@ def changelist_view(self, request, extra_context=None):
"""
The 'change list' admin view for this model.
"""
return ChangeListView(
return AdminChangeListView(
admin_opts=self, extra_context=extra_context).dispatch(request)

@csrf_protect_m
Expand All @@ -958,7 +958,7 @@ def history_view(self, request, object_id, extra_context=None):
"""
The 'history' admin view for this model.
"""
return HistoryView(
return AdminHistoryView(
admin_opts=self, extra_context=extra_context,
object_id=object_id).dispatch(request)

Expand Down
4 changes: 2 additions & 2 deletions django/contrib/admin/templatetags/admin_list.py
Expand Up @@ -2,7 +2,7 @@

from django.contrib.admin.util import (lookup_field, display_for_field,
display_for_value, label_for_field)
from django.contrib.admin.views.main import (ALL_VAR, EMPTY_CHANGELIST_VALUE,
from django.contrib.admin.views.list import (ALL_VAR, EMPTY_CHANGELIST_VALUE,
ORDER_VAR, PAGE_VAR, SEARCH_VAR)
from django.contrib.admin.templatetags.admin_static import static
from django.core.exceptions import ObjectDoesNotExist
Expand All @@ -12,7 +12,7 @@
from django.utils.safestring import mark_safe
from django.utils.text import capfirst
from django.utils.translation import ugettext as _
from django.utils.encoding import smart_unicode, force_unicode
from django.utils.encoding import force_unicode
from django.template import Library
from django.template.loader import get_template
from django.template.context import Context
Expand Down
4 changes: 2 additions & 2 deletions django/contrib/admin/util.py
Expand Up @@ -314,7 +314,7 @@ def help_text_for_field(name, model):

def display_for_field(value, field):
from django.contrib.admin.templatetags.admin_list import _boolean_icon
from django.contrib.admin.views.main import EMPTY_CHANGELIST_VALUE
from django.contrib.admin.views.list import EMPTY_CHANGELIST_VALUE

if field.flatchoices:
return dict(field.flatchoices).get(value, EMPTY_CHANGELIST_VALUE)
Expand All @@ -338,7 +338,7 @@ def display_for_field(value, field):

def display_for_value(value, boolean=False):
from django.contrib.admin.templatetags.admin_list import _boolean_icon
from django.contrib.admin.views.main import EMPTY_CHANGELIST_VALUE
from django.contrib.admin.views.list import EMPTY_CHANGELIST_VALUE

if boolean:
return _boolean_icon(value)
Expand Down
4 changes: 4 additions & 0 deletions django/contrib/admin/views/__init__.py
@@ -0,0 +1,4 @@
from django.contrib.admin.views.edit import (
AdminDeleteView, AdminAddView, AdminChangeView)
from django.contrib.admin.views.list import AdminChangeListView
from django.contrib.admin.views.history import AdminHistoryView
10 changes: 10 additions & 0 deletions django/contrib/admin/views/base.py
@@ -0,0 +1,10 @@

class AdminViewMixin(object):

def __init__(self, **kwargs):
super(AdminViewMixin, self).__init__(**kwargs)
self.model = self.admin_opts.model
self.model_opts = self.model._meta

def get_queryset(self):
return self.admin_opts.queryset(self.request)
@@ -1,243 +1,15 @@
from django.core.exceptions import PermissionDenied
from django.core.urlresolvers import reverse
from django.http import Http404, HttpResponseRedirect
from django.shortcuts import get_object_or_404
from django.utils.encoding import force_unicode
from django.views.generic.base import TemplateView
from django.utils.translation import ugettext as _
from django.views.generic.edit import UpdateView, CreateView, DeleteView
from django.utils.translation import ugettext as _, ungettext
from django.contrib.admin.util import unquote, get_deleted_objects
from django.contrib.admin.views.base import AdminViewMixin
from django.forms.formsets import all_valid
from django.contrib.admin import helpers
from django.utils.html import escape
from django.db import transaction, models, router
from django.views.decorators.csrf import csrf_protect
from django.utils.decorators import method_decorator
from django.contrib.admin.views.main import ERROR_FLAG
from django.template.response import SimpleTemplateResponse
from django.utils.text import capfirst
from django.contrib.contenttypes.models import ContentType


csrf_protect_m = method_decorator(csrf_protect)


class AdminViewMixin(object):

def __init__(self, **kwargs):
super(AdminViewMixin, self).__init__(**kwargs)
self.model = self.admin_opts.model
self.model_opts = self.model._meta

def get_queryset(self):
return self.admin_opts.queryset(self.request)


class HistoryView(AdminViewMixin, TemplateView):

def get_context_data(self, **kwargs):
from django.contrib.admin.models import LogEntry

context = super(HistoryView, self).get_context_data(**kwargs)

action_list = LogEntry.objects.filter(
object_id = self.object_id,
content_type__id__exact = ContentType.objects.get_for_model(self.model).id
).select_related().order_by('action_time')
# If no history was found, see whether this object even exists.
obj = get_object_or_404(self.model, pk=unquote(self.object_id))

context.update({
'title': _('Change history: %s') % force_unicode(obj),
'action_list': action_list,
'module_name': capfirst(force_unicode(self.model_opts.verbose_name_plural)),
'object': obj,
'app_label': self.model_opts.app_label,
'opts': self.model_opts,
})

context.update(self.extra_context or {})
return context

def get_template_names(self):
form_template = self.admin_opts.object_history_template
if form_template:
return [form_template]
else:
return [
"admin/%s/%s/object_history.html" % (self.model_opts.app_label, self.model_opts.object_name.lower()),
"admin/%s/object_history.html" % self.model_opts.app_label,
"admin/object_history.html"
]


class ChangeListView(AdminViewMixin, TemplateView):

def dispatch(self, request, *args, **kwargs):
from django.contrib.admin.options import IncorrectLookupParameters

if not self.admin_opts.has_change_permission(request, None):
raise PermissionDenied

list_display = self.admin_opts.get_list_display(request)
list_display_links = self.admin_opts.get_list_display_links(request, list_display)

# Check actions to see if any are available on this changelist
self.actions = self.admin_opts.get_actions(request)
if self.actions:
# Add the action checkboxes if there are any actions available.
list_display = ['action_checkbox'] + list(list_display)

ChangeList = self.admin_opts.get_changelist(request)
try:
self.changelist = ChangeList(request, self.admin_opts.model, list_display,
list_display_links, self.admin_opts.list_filter, self.admin_opts.date_hierarchy,
self.admin_opts.search_fields, self.admin_opts.list_select_related,
self.admin_opts.list_per_page, self.admin_opts.list_max_show_all, self.admin_opts.list_editable,
self.admin_opts)
except IncorrectLookupParameters:
# Wacky lookup parameters were given, so redirect to the main
# changelist page, without parameters, and pass an 'invalid=1'
# parameter via the query string. If wacky parameters were given
# and the 'invalid=1' parameter was already in the query string,
# something is screwed up with the database, so display an error
# page.
if ERROR_FLAG in request.GET.keys():
return SimpleTemplateResponse('admin/invalid_setup.html', {
'title': _('Database error'),
})
return HttpResponseRedirect(request.path + '?' + ERROR_FLAG + '=1')

# If we're allowing changelist editing, we need to construct a formset
# for the changelist given all the fields to be edited. Then we'll
# use the formset to validate/process POSTed data.
self.formset = self.changelist.formset = None

return super(ChangeListView, self).dispatch(request, *args, **kwargs)

def post(self, request, *args, **kwargs):
# If the request was POSTed, this might be a bulk action or a bulk
# edit. Try to look up an action or confirmation first, but if this
# isn't an action the POST will fall through to the bulk edit check,
# below.
action_failed = False
selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME)

# Actions with no confirmation
if (self.actions and request.method == 'POST' and
'index' in request.POST and '_save' not in request.POST):
if selected:
response = self.admin_opts.response_action(request, queryset=self.changelist.get_query_set(request))
if response:
return response
else:
action_failed = True
else:
msg = _("Items must be selected in order to perform "
"actions on them. No items have been changed.")
self.admin_opts.message_user(request, msg)
action_failed = True

# Actions with confirmation
if (self.actions and
helpers.ACTION_CHECKBOX_NAME in request.POST and
'index' not in request.POST and
'_save' not in request.POST and
selected):
response = self.admin_opts.response_action(request, queryset=self.changelist.get_query_set(request))
if response:
return response
else:
action_failed = True

# Handle POSTed bulk-edit data.
if (self.changelist.list_editable and
'_save' in request.POST and not action_failed):
FormSet = self.admin_opts.get_changelist_formset(request)
self.formset = self.changelist.formset = FormSet(request.POST, request.FILES, queryset=self.changelist.result_list)
if self.formset.is_valid():
changecount = 0
for form in self.formset.forms:
if form.has_changed():
obj = self.admin_opts.save_form(request, form, change=True)
self.admin_opts.save_model(request, obj, form, change=True)
self.admin_opts.save_related(request, form, formsets=[], change=True)
change_msg = self.admin_opts.construct_change_message(request, form, None)
self.admin_opts.log_change(request, obj, change_msg)
changecount += 1

if changecount:
if changecount == 1:
name = force_unicode(self.model_opts.verbose_name)
else:
name = force_unicode(self.model_opts.verbose_name_plural)
msg = ungettext("%(count)s %(name)s was changed successfully.",
"%(count)s %(name)s were changed successfully.",
changecount) % {'count': changecount,
'name': name,
'obj': force_unicode(obj)}
self.admin_opts.message_user(request, msg)

return HttpResponseRedirect(request.get_full_path())

return self.render_to_response(self.get_context_data(), current_app=self.admin_opts.admin_site.name)

def get(self, request, *args, **kwargs):
# Handle GET -- construct a formset for display.
if self.changelist.list_editable:
FormSet = self.admin_opts.get_changelist_formset(request)
self.formset = self.changelist.formset = FormSet(queryset=self.changelist.result_list)
return self.render_to_response(self.get_context_data(), current_app=self.admin_opts.admin_site.name)

def get_template_names(self):
form_template = self.admin_opts.change_list_template
if form_template:
return [form_template]
else:
return [
"admin/%s/%s/change_list.html" % (self.model_opts.app_label, self.model_opts.object_name.lower()),
"admin/%s/change_list.html" % self.model_opts.app_label,
"admin/change_list.html"
]

def get_context_data(self, **kwargs):
context = super(ChangeListView, self).get_context_data(**kwargs)

# Build the list of media to be used by the formset.
if self.formset:
media = self.admin_opts.media + self.formset.media
else:
media = self.admin_opts.media

# Build the action form and populate it with available actions.
if self.actions:
self.action_form = self.admin_opts.action_form(auto_id=None)
self.action_form.fields['action'].choices = self.admin_opts.get_action_choices(self.request)
else:
self.action_form = None

selection_note_all = ungettext('%(total_count)s selected',
'All %(total_count)s selected', self.changelist.result_count)

context.update({
'module_name': force_unicode(self.model_opts.verbose_name_plural),
'selection_note': _('0 of %(cnt)s selected') % {'cnt': len(self.changelist.result_list)},
'selection_note_all': selection_note_all % {'total_count': self.changelist.result_count},
'title': self.changelist.title,
'is_popup': self.changelist.is_popup,
'cl': self.changelist,
'media': media,
'has_add_permission': self.admin_opts.has_add_permission(self.request),
'app_label': self.model_opts.app_label,
'action_form': self.action_form,
'actions_on_top': self.admin_opts.actions_on_top,
'actions_on_bottom': self.admin_opts.actions_on_bottom,
'actions_selection_counter': self.admin_opts.actions_selection_counter,
})

context.update(self.extra_context or {})
return context

from django.db import models, router


class AdminDeleteView(AdminViewMixin, DeleteView):
Expand Down

0 comments on commit 27f8d4b

Please sign in to comment.