zoukankan      html  css  js  c++  java
  • Django源码解读——ModelAdmin方法解读

    本期解读源码:
    django.contrib.adminModelAdmin类中方法changelist_view

        def changelist_view(self, request, extra_context=None):
            """
            The 'change list' admin view for this model.
            changelist_view管理视图函数主要用于django自带后台admin管理模型时,用户初始看到的模型信息显示列表
            视图函数一共有三个参数
                self:代表ModelAdmin类本身
                request:代表这次请求
                extra_context:代表额外的信息,这里extra_context默认为None,说明在访问这个方法时,即便是没带上extra_context也能正常访问
            """
    # 从django.contrib.admin.views.main导入错误报警ERROR_FLAG
            from django.contrib.admin.views.main import ERROR_FLAG
            # opts为当前管理模型的Meta属性,可理解为当前管理模型的别名
            opts = self.model._meta
            # 当前管理模型的app标签,这个在app.py和init.py中设置
            app_label = opts.app_label
            # 判断当前请求用户有没有查看或者修改权限,没有抛出异常PermissionDenied
            if not self.has_view_or_change_permission(request):
                raise PermissionDenied
    
            try:
                #尝试得到请求数据列表的实例
                cl = self.get_changelist_instance(request)
            # 如果不能正常得到,捕获异常IncorrectLookupParameters
            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:
                    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按钮是未被点击的
            action_failed = False
            # 得到被选择的项目的列表
            selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME)
            
            # 得到请求的action
            actions = self.get_actions(request)
            # 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:
                if not self.has_change_permission(request):
                    raise PermissionDenied
                FormSet = self.get_changelist_formset(request)
                modified_objects = self._get_list_editable_queryset(request, FormSet.get_default_prefix())
                formset = cl.formset = FormSet(request.POST, request.FILES, queryset=modified_objects)
                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),
                        }
                        self.message_user(request, msg, messages.SUCCESS)
    
                    return HttpResponseRedirect(request.get_full_path())
    
            # Handle GET -- construct a formset for display.
            elif cl.list_editable and self.has_change_permission(request):
                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 = {
                **self.admin_site.each_context(request),
                'module_name': str(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),
                **(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)
    
  • 相关阅读:
    第三章-列表简介
    第二章—变量和简单数据类型
    CSS3转换
    maven项目报:An error occurred while filtering resources
    CSS基本知识和选择器
    Html
    算法(第四版)学习笔记(三)——归并排序
    算法学习笔记(二)——初级排序算法
    算法学习(一)——二分查找递归方法
    1003. 我要通过!(20)
  • 原文地址:https://www.cnblogs.com/donoho/p/11577076.html
Copyright © 2011-2022 走看看