Пример #1
0
	def changelist_view(self, request, extra_context=None):
		# Get a query set with same filters as the current change list
		from django.contrib.admin.views.main import ChangeList
		from datetime import timedelta
		cl = ChangeList(request, self.model, self.list_display, self.list_display_links, 
						self.list_filter, self.date_hierarchy, self.search_fields, 
						self.list_select_related, self.list_per_page, self.list_max_show_all, 
						self.list_editable, self)

		filtered_query_set = cl.get_queryset(request)
		hours = timedelta()
		for hour in [entry.hours for entry in filtered_query_set]:
			hours += timedelta(hours=hour.hour,minutes=hour.minute)
		
		seconds = hours.days * 86400 + hours.seconds
		hours, remainder = divmod(seconds, 3600)
		minutes, seconds = divmod(remainder, 60)
		total_hours = '%02d:%02d' % (hours, minutes)
							
		extra = {
			'total_hours': total_hours,
		}

		if extra_context: extra = extra.update(extra_context)
		
		return super(EntryAdmin, self).changelist_view(request, extra_context=extra)
Пример #2
0
    def changelist_view(self, request, extra_context=None):
        from django.contrib.admin.views.main import ChangeList
        cl = ChangeList(request, self.model, list(self.list_display),
                        self.list_display_links, self.list_filter,
                        self.date_hierarchy, self.search_fields,
                        self.list_select_related,
                        self.list_per_page,
                        self.list_max_show_all,
                        self.list_editable,
                        self)


        total_dict = dict()
        outstanding_dict = dict()
        for currency, description in br_settings.INVOICE_CURRENCY_CHOICES:
            # Determine total and subtotal
            subtotal = Decimal(0)
            total = Decimal(0)
            for invoice in cl.get_queryset(request).filter(status=4,
                                                           currency=currency):
                subtotal += invoice.subtotal
                total += invoice.total

            # Add to dictionary
            if total > 0:
                subtotal = decimal_to_string(subtotal, currency)
                total = decimal_to_string(total, currency)
                total_dict[description.lower()] = [subtotal, total]

            subtotal = Decimal(0)
            total = Decimal(0)
            for invoice in cl.get_queryset(request).filter(
                    status__in=[1, 2, 3], currency=currency):
                subtotal += invoice.subtotal
                total += invoice.total

            # Add to dictionary
            if total > 0:
                subtotal = decimal_to_string(subtotal, currency)
                total = decimal_to_string(total, currency)
                outstanding_dict[description.lower()] = [subtotal, total]

        extra_context = dict()
        extra_context['total_dict'] = total_dict
        extra_context['outstanding_dict'] = outstanding_dict
        return super(InvoiceAdmin, self).changelist_view(
            request, extra_context=extra_context)
Пример #3
0
 def filtered_request_queryset(self, request):
     """Return queryset filtered by the admin list view"""
     cl = ChangeList(request, self.model, self.list_display,
                     self.list_display_links, self.list_filter,
                     self.date_hierarchy, self.search_fields,
                     self.list_select_related, self.list_per_page,
                     self.list_editable, self)
     return cl.get_queryset()
Пример #4
0
def obtener_listado_admin(
  self,
  model,
  my_admin=CustomModelAdmin,
  queryset=None):
  
  #custom_site.register(model,model)

  my_admin = my_admin(model,custom_site)
  if queryset != None:
    nuevo_queryset = queryset
    my_admin.set_queryset(nuevo_queryset)
    
  list_display = ['action_checkbox'] + list(my_admin.list_display)
  
  my_admin.show_admin_actions = True
  my_admin.actions = my_admin.get_actions(self)
  action_form = my_admin.action_form(self.POST)
  action_form.fields['action'].choices = my_admin.get_action_choices(self)

  ChangeList = my_admin.get_changelist(self)

  listado = ChangeList(
    self,
    model,
    list_display,
    my_admin.get_list_display_links(self,my_admin.list_display),
    my_admin.list_filter,
    my_admin.date_hierarchy,
    my_admin.search_fields,
    my_admin.list_select_related,
    my_admin.list_per_page,
    my_admin.list_max_show_all,
    my_admin.list_editable,
    my_admin)
  
  selected = self.POST.getlist(helpers.ACTION_CHECKBOX_NAME)

  if selected:
    response = my_admin.response_action(self,queryset=listado.get_queryset(self))
    if type(response) is HttpResponse:
      return response
  
  #if not selected and self.POST:
  #  messages.error(self, 'No selecciono ningun elemento. No se afecto ningún elemento')

  listado.formset = None

  parametros = {
    'cl'                        : listado,
    'action_form'               : action_form,
    'actions_selection_counter' : my_admin.actions_selection_counter
  }

  return parametros
Пример #5
0
    def export_as_csv(self, request, header=True, safe_mode=False):
        extra_file_name = ''
        opts = self.model._meta
        field_names = [f.name for f in opts.fields]
        field_names = list(self.list_display) + field_names
        # Make unique sequence with ordering.
        unique = set()
        unique_add = unique.add
        field_names = [
            x for x in field_names if x not in unique and not unique_add(x)
        ]

        if hasattr(self, 'csv_field_exclude'):
            field_names = [
                f for f in field_names if not f in self.csv_field_exclude
            ]

        if safe_mode:
            extra_file_name = '_safe'
            if hasattr(self, 'csv_safe_fields'):
                field_names = [
                    f for f in field_names if not f in self.csv_safe_fields
                ]

        labels = self._get_labels(field_names)

        response = HttpResponse(mimetype='text/csv')
        response['Content-Disposition'] = 'attachment; filename=%s%s.csv' % (
            unicode(opts).replace('.', '_'), extra_file_name)

        writer = csv.writer(response, delimiter=';')

        if header:
            writer.writerow([unicode(label).capitalize() for label in labels])

        list_display = self.get_list_display(request)
        list_display_links = self.get_list_display_links(request, list_display)
        list_filter = self.get_list_filter(request)
        ChangeList = self.get_changelist(request)
        cl = ChangeList(request, self.model, list_display, list_display_links,
                        list_filter, self.date_hierarchy, self.search_fields,
                        self.list_select_related, self.list_per_page,
                        self.list_max_show_all, self.list_editable, self)

        queryset = self.make_tracking_queryset(cl.get_queryset(request))
        for obj in queryset:
            fields = []
            for field in field_names:
                try:
                    fields.append(self._prep_field(obj, field))
                except ObjectDoesNotExist:
                    fields.append('')
            writer.writerow(fields)
        return response
Пример #6
0
 def filtered_request_queryset(self, request):
     """Return queryset filtered by the admin list view"""
     list_display = self.get_list_display(request)
     list_display_links = self.get_list_display_links(request, list_display)
     cl = ChangeList(request, self.model, list_display,
                     list_display_links, self.list_filter,
                     self.date_hierarchy, self.search_fields,
                     self.list_select_related, self.list_per_page,
                     self.list_max_show_all, self.list_editable,
                     self)
     return cl.get_queryset(request)
Пример #7
0
    def export_as_csv(self, request, header=True, safe_mode=False):
        extra_file_name = ''
        opts = self.model._meta
        field_names = [f.name for f in opts.fields]
        field_names = list(self.list_display) + field_names
        # Make unique sequence with ordering.
        unique = set()
        unique_add = unique.add
        field_names = [x for x in field_names
                       if x not in unique and not unique_add(x)]

        if hasattr(self, 'csv_field_exclude'):
            field_names = [f for f in field_names
                           if not f in self.csv_field_exclude]

        if safe_mode:
            extra_file_name = '_safe'
            if hasattr(self, 'csv_safe_fields'):
                field_names = [f for f in field_names
                               if not f in self.csv_safe_fields]

        labels = self._get_labels(field_names)

        response = HttpResponse(mimetype='text/csv')
        response['Content-Disposition'] = 'attachment; filename=%s%s.csv' % (
            unicode(opts).replace('.', '_'), extra_file_name
        )

        writer = csv.writer(response, delimiter=';')

        if header:
            writer.writerow([unicode(label).capitalize() for label in labels])

        list_display = self.get_list_display(request)
        list_display_links = self.get_list_display_links(request, list_display)
        list_filter = self.get_list_filter(request)
        ChangeList = self.get_changelist(request)
        cl = ChangeList(request, self.model, list_display,
                        list_display_links, list_filter, self.date_hierarchy,
                        self.search_fields, self.list_select_related,
                        self.list_per_page, self.list_max_show_all, self.list_editable,
                        self)

        queryset = self.make_tracking_queryset(cl.get_queryset(request))
        for obj in queryset:
            fields = []
            for field in field_names:
                try:
                    fields.append(self._prep_field(obj, field))
                except ObjectDoesNotExist:
                    fields.append('')
            writer.writerow(fields)
        return response
Пример #8
0
    def get_change_list_query_set(self, request, extra_context=None):
        """
        The 'change list' admin view for this model.
        """
        list_display = self.get_list_display(request)
        list_display_links = self.get_list_display_links(request, list_display)
        list_filter = self.get_list_filter(request)
        ChangeList = self.get_changelist(request)

        cl = ChangeList(request, self.model, list_display, list_display_links,
                        list_filter, self.date_hierarchy, self.search_fields,
                        self.list_select_related, self.list_per_page,
                        self.list_max_show_all, self.list_editable, self)
        return cl.get_queryset(request)
Пример #9
0
    def get_change_list_query_set(self, request, extra_context=None):
        """
        The 'change list' admin view for this model.
        """
        list_display = self.get_list_display(request)
        list_display_links = self.get_list_display_links(request, list_display)
        list_filter = self.get_list_filter(request)
        ChangeList = self.get_changelist(request)

        cl = ChangeList(request, self.model, list_display,
            list_display_links, list_filter, self.date_hierarchy,
            self.search_fields, self.list_select_related,
            self.list_per_page, self.list_max_show_all, self.list_editable,
            self)
        return cl.get_queryset(request)
Пример #10
0
    def changelist_view(self, request, extra_context=None):
        """
        The 'change list' admin view for this model.
        """
        from django.contrib.admin.views.main import ERROR_FLAG
        opts = self.model._meta
        app_label = opts.app_label
        if not self.has_change_permission(request, None):
            raise PermissionDenied

        list_display = self.get_list_display(request)
        list_display_links = self.get_list_display_links(request, list_display)
        list_filter = self.get_list_filter(request)
        search_fields = self.get_search_fields(request)
        list_select_related = self.get_list_select_related(request)

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

        ChangeList = self.get_changelist(request)
        try:
            cl = ChangeList(
                request, self.model, list_display,
                list_display_links, list_filter, self.date_hierarchy,
                search_fields, list_select_related, self.list_per_page,
                self.list_max_show_all, self.list_editable, 
                self, self.list_display_mobile, 
            )
        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 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 (actions and request.method == 'POST' and
                'index' in request.POST and '_save' not in request.POST):
            if selected:
                response = self.response_action(request, queryset=cl.get_queryset(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.message_user(request, msg, messages.WARNING)
                action_failed = True

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

        if action_failed:
            # Redirect back to the changelist page to avoid resubmitting the
            # form if the user refreshes the browser or uses the "No, take
            # me back" button on the action confirmation page.
            return HttpResponseRedirect(request.get_full_path())

        # 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.
        formset = cl.formset = None

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

                if changecount:
                    msg = ngettext(
                        "%(count)s %(name)s was changed successfully.",
                        "%(count)s %(name)s were changed successfully.",
                        changecount
                    ) % {
                        'count': changecount,
                        'name': model_ngettext(opts, changecount),
                        'obj': force_text(obj),
                    }
                    self.message_user(request, msg, messages.SUCCESS)

                return HttpResponseRedirect(request.get_full_path())

        # Handle GET -- construct a formset for display.
        elif cl.list_editable:
            FormSet = self.get_changelist_formset(request)
            formset = cl.formset = FormSet(queryset=cl.result_list)

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

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

        selection_note_all = ngettext(
            '%(total_count)s selected',
            'All %(total_count)s selected',
            cl.result_count
        )

        context = dict(
            self.admin_site.each_context(request),
            module_name=force_text(opts.verbose_name_plural),
            selection_note=_('0 of %(cnt)s selected') % {'cnt': len(cl.result_list)},
            selection_note_all=selection_note_all % {'total_count': cl.result_count},
            title=cl.title,
            is_popup=cl.is_popup,
            to_field=cl.to_field,
            cl=cl,
            media=media,
            has_add_permission=self.has_add_permission(request),
            opts=cl.opts,
            action_form=action_form,
            actions_on_top=self.actions_on_top,
            actions_on_bottom=self.actions_on_bottom,
            actions_selection_counter=self.actions_selection_counter,
            preserved_filters=self.get_preserved_filters(request),
        )
        context.update(extra_context or {})

        request.current_app = self.admin_site.name

        return TemplateResponse(request, self.change_list_template or [
            'admin/%s/%s/change_list.html' % (app_label, opts.model_name),
            'admin/%s/change_list.html' % app_label,
            'admin/change_list.html'
        ], context)
Пример #11
0
    def changelist_view(self, request, extra_context=None):
        "The 'change list' admin view for this model."
        opts = self.model._meta
        app_label = opts.app_label

        # Check actions to see if any are available on this changelist
        actions = self.get_actions(request)

        # Remove action checkboxes if there aren't any actions available.
        list_display = list(self.list_display)
        if not actions:
            try:
                list_display.remove('action_checkbox')
            except ValueError:
                pass

        ChangeList = self.get_changelist(request)
        try:
            cl = ChangeList(request, self.model, list_display,
                            self.list_display_links, self.list_filter,
                            self.date_hierarchy, self.search_fields,
                            self.list_select_related, self.list_per_page,
                            self.list_max_show_all, self.list_editable, self,
                            self.sortable_by)
        except adminoptions.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 render_to_response('admin/invalid_setup.html',
                                          {'title': ('Database error')})
            return HttpResponseRedirect(request.path + '?' + ERROR_FLAG + '=1')

        # if auto_redirect is true we should handle that before anything else
        if self.auto_redirect and cl.queryset.count() == 1:

            obj = cl.queryset[0]
            try:
                url = obj.get_absolute_url()
            except AttributeError:
                url = None

            if url:  # if no url just go ahead and show the display set normally
                return HttpResponseRedirect(url)

        # 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 actions and request.method == 'POST':
            response = self.response_action(request,
                                            queryset=cl.get_queryset(request))
            if response:
                return response

        # 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.
        formset = cl.formset = None

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

                if changecount:
                    if changecount == 1:
                        name = force_text(opts.verbose_name)
                    else:
                        name = force_text(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_text(obj)
                        }
                    self.message_user(request, msg)

                return HttpResponseRedirect(request.get_full_path())

        # Handle GET -- construct a formset for display.
        elif self.list_editable:
            FormSet = self.get_changelist_formset(request)
            formset = cl.formset = FormSet(queryset=cl.result_list)

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

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

        # Build the columns form
        column_form_choices = []
        column_form_initial = []
        default_display = getattr(cl.model_admin, "list_display_default", [])

        for item in cl.list_display + cl.list_display_options:

            if item in default_display or item == 'action_checkbox':
                continue

            name = getattr(item, "__name__", item)

            display_name = getattr(item, "short_description", pretty(name))

            if not (name, display_name) in column_form_choices:
                column_form_choices.append((name, display_name))

            if item in cl.list_display:
                column_form_initial.append(name)

        columns_form = ColumnsForm(request.GET or None)
        columns_form.fields['columns'].choices = column_form_choices
        columns_form.fields['columns'].initial = column_form_initial

        context = {
            'module_name': force_text(opts.verbose_name_plural),
            'columns_form': columns_form,
            'title': cl.title,
            'is_popup': cl.is_popup,
            'cl': cl,
            'media': media,
            'has_add_permission': self.has_add_permission(request),
            'root_path': self.admin_site.root_path,
            'app_label': app_label,
            'action_form': action_form,
            'actions_on_top': self.actions_on_top,
            'actions_on_bottom': self.actions_on_bottom,
            'actions_selection_counter': self.actions_selection_counter,
            'opts': self.opts
        }
        context.update(extra_context or {})
        return render(request,
                      self.change_list_template or [
                          'admin/%s/%s/change_list.html' %
                          (app_label, opts.object_name.lower()),
                          'admin/%s/change_list.html' % app_label,
                          'admin/change_list.html'
                      ],
                      context=context)
Пример #12
0
    def changelist_view(self,  request,  extra_context=None):
        "The 'change list' admin view for this model."
        opts = self.model._meta
        app_label = opts.app_label

        # Check actions to see if any are available on this changelist
        actions = self.get_actions(request)

        # Remove action checkboxes if there aren't any actions available.
        list_display = list(self.list_display)
        if not actions:
            try:
                list_display.remove('action_checkbox')
            except ValueError:
                pass

        ChangeList = self.get_changelist(request)
        try:
            cl = ChangeList(request,  self.model,  list_display,  self.list_display_links,  self.list_filter,
                self.date_hierarchy,  self.search_fields,  self.list_select_related,  self.list_per_page,
                self.list_max_show_all,  self.list_editable,  self)
        except adminoptions.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 render_to_response('admin/invalid_setup.html',  {'title': ('Database error')})
            return HttpResponseRedirect(request.path + '?' + ERROR_FLAG + '=1')

        # if auto_redirect is true we should handle that before anything else
        if self.auto_redirect and cl.queryset.count() == 1:

            obj = cl.queryset[0]
            try:
                url = obj.get_absolute_url()
            except AttributeError:
                url = None

            if url: # if no url just go ahead and show the display set normally
                return HttpResponseRedirect(url)

        # 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 actions and request.method == 'POST':
            response = self.response_action(request,  queryset=cl.get_queryset(request))
            if response:
                return response

        # 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.
        formset = cl.formset = None

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

                if changecount:
                    if changecount == 1:
                        name = force_unicode(opts.verbose_name)
                    else:
                        name = force_unicode(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.message_user(request,  msg)

                return HttpResponseRedirect(request.get_full_path())

        # Handle GET -- construct a formset for display.
        elif self.list_editable:
            FormSet = self.get_changelist_formset(request)
            formset = cl.formset = FormSet(queryset=cl.result_list)

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

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

        # Build the columns form
        column_form_choices = []
        column_form_initial = []
        default_display = getattr(cl.model_admin,  "list_display_default",  [])

        for item in cl.list_display + cl.list_display_options:

            if item in default_display or item == 'action_checkbox':
                continue

            name = getattr(item, "func_name", item)

            display_name = getattr(item, "short_description", pretty(name))

            if not (name, display_name) in column_form_choices:
                column_form_choices.append((name, display_name))

            if item in cl.list_display:
                column_form_initial.append(name)

        columns_form = ColumnsForm(request.GET or None)
        columns_form.fields['columns'].choices = column_form_choices
        columns_form.fields['columns'].initial = column_form_initial

        context = {
            'module_name': force_unicode(opts.verbose_name_plural),
            'columns_form': columns_form,
            'title': cl.title,
            'is_popup': cl.is_popup,
            'cl': cl,
            'media': media,
            'has_add_permission': self.has_add_permission(request),
            'root_path': self.admin_site.root_path,
            'app_label': app_label,
            'action_form': action_form,
            'actions_on_top': self.actions_on_top,
            'actions_on_bottom': self.actions_on_bottom,
            'actions_selection_counter': self.actions_selection_counter,
        }
        context.update(extra_context or {})
        return render(request, self.change_list_template or [
            'admin/%s/%s/change_list.html' % (app_label,  opts.object_name.lower()),
            'admin/%s/change_list.html' % app_label,
            'admin/change_list.html'
        ],  context=context)