from __future__ import absolute_import
from collections import OrderedDict
from django.core.exceptions import PermissionDenied, ObjectDoesNotExist
from django.core.paginator import InvalidPage, Paginator
from django.urls.base import NoReverseMatch
from django.db import models
from django.http import HttpResponseRedirect
from django.template.response import SimpleTemplateResponse, TemplateResponse
from django.utils import six
from django.utils.encoding import force_text, smart_text
from django.utils.html import escape, conditional_escape
from django.utils.safestring import mark_safe
from django.utils.text import capfirst
from django.utils.translation import ugettext as _
from xadmin.util import lookup_field, display_for_field, label_for_field, boolean_icon
from .base import ModelAdminView, filter_hook, inclusion_tag, csrf_protect_m
# List settings
ALL_VAR = 'all'
ORDER_VAR = 'o'
PAGE_VAR = 'p'
TO_FIELD_VAR = 't'
COL_LIST_VAR = '_cols'
ERROR_FLAG = 'e'
DOT = '.'
# Text to display within change-list table cells if the value is blank.
EMPTY_CHANGELIST_VALUE = _('Null')
class FakeMethodField(object):
"""
This class used when a column is an model function, wrap function as a fake field to display in select columns.
"""
def __init__(self, name, verbose_name):
# Initial comm field attrs
self.name = name
self.verbose_name = verbose_name
self.primary_key = False
class ResultRow(dict):
pass
class ResultItem(object):
def __init__(self, field_name, row):
self.classes = []
self.text = ' '
self.wraps = []
self.tag = 'td'
self.tag_attrs = []
self.allow_tags = False
self.btns = []
self.menus = []
self.is_display_link = False
self.row = row
self.field_name = field_name
self.field = None
self.attr = None
self.value = None
@property
def label(self):
text = mark_safe(
self.text) if self.allow_tags else conditional_escape(self.text)
if force_text(text) == '':
text = mark_safe(' ')
for wrap in self.wraps:
text = mark_safe(wrap % text)
return text
@property
def tagattrs(self):
return mark_safe(
'%s%s' % ((self.tag_attrs and ' '.join(self.tag_attrs) or ''),
(self.classes and (' class="%s"' % ' '.join(self.classes)) or '')))
class ResultHeader(ResultItem):
def __init__(self, field_name, row):
super(ResultHeader, self).__init__(field_name, row)
self.tag = 'th'
self.tag_attrs = ['scope="col"']
self.sortable = False
self.allow_tags = True
self.sorted = False
self.ascending = None
self.sort_priority = None
self.url_primary = None
self.url_remove = None
self.url_toggle = None
class ListAdminView(ModelAdminView):
"""
Display models objects view. this class has ordering and simple filter features.
"""
list_display = ('__str__',)
list_display_links = ()
list_display_links_details = False
list_select_related = None
list_per_page = 50
list_max_show_all = 200
list_exclude = ()
search_fields = ()
paginator_class = Paginator
ordering = None
# Change list templates
object_list_template = None
def init_request(self, *args, **kwargs):
if not self.has_view_permission():
raise PermissionDenied
request = self.request
request.session['LIST_QUERY'] = (self.model_info, self.request.META['QUERY_STRING'])
self.pk_attname = self.opts.pk.attname
self.lookup_opts = self.opts
self.list_display = self.get_list_display()
self.list_display_links = self.get_list_display_links()
# Get page number parameters from the query string.
try:
self.page_num = int(request.GET.get(PAGE_VAR, 0))
except ValueError:
self.page_num = 0
# Get params from request
self.show_all = ALL_VAR in request.GET
self.to_field = request.GET.get(TO_FIELD_VAR)
self.params = dict(request.GET.items())
if PAGE_VAR in self.params:
del self.params[PAGE_VAR]
if ERROR_FLAG in self.params:
del self.params[ERROR_FLAG]
@filter_hook
def get_list_display(self):
"""
Return a sequence containing the fields to be displayed on the list.
"""
self.base_list_display = (COL_LIST_VAR in self.request.GET and self.request.GET[COL_LIST_VAR] != "" and
self.request.GET[COL_LIST_VAR].split('.')) or self.list_display
return list(self.base_list_display)
@filter_hook
def get_list_display_links(self):
"""
Return a sequence containing the fields to be displayed as links
on the changelist. The list_display parameter is the list of fields
returned by get_list_display().
"""
if self.list_display_links or not self.list_display:
return self.list_display_links
else:
# Use only the first item in list_display as link
return list(self.list_display)[:1]
def make_result_list(self):
# Get search parameters from the query string.
self.list_queryset = self.get_list_queryset()
self.ordering_field_columns = self.get_ordering_field_columns()
self.paginator = self.get_paginator()
# Get the number of objects, with admin filters applied.
self.result_count = self.paginator.count
self.can_show_all = self.result_count <= self.list_max_show_all
self.multi_page = self.result_count > self.list_per_page
# Get the list of objects to display on this page.
if (self.show_all and self.can_show_all) or not self.multi_page:
self.result_list = self.list_queryset._clone()
else:
try:
self.result_list = self.paginator.page(
self.page_num + 1).object_list
except InvalidPage:
if ERROR_FLAG in self.request.GET.keys():
return SimpleTemplateResponse('xadmin/views/invalid_setup.html', {
'title': _('Database error'),
})
return HttpResponseRedirect(self.request.path + '?' + ERROR_FLAG + '=1')
self.has_more = self.result_count > (
self.list_per_page * self.page_num + len(self.result_list))
@filter_hook
def get_result_list(self):
return self.make_result_list()
@filter_hook
def post_result_list(self):
return self.make_result_list()
@filter_hook
def get_list_queryset(self):
"""
Get model queryset. The query has been filted and ordered.
"""
# First, get queryset from base class.
queryset = self.queryset()
# Use select_related() if one of the list_display options is a field
# with a relationship and the provided queryset doesn't already have
# select_related defined.
if not queryset.query.select_related:
if self.list_select_related:
queryset = queryset.select_related()
elif self.list_select_related is None:
related_fields = []
for field_name in self.list_display:
try:
field = self.opts.get_field(field_name)
except models.FieldDoesNotExist:
pass
else:
if isinstance(field.remote_field, models.ManyToOneRel):
related_fields.append(field_name)
if related_fields:
queryset = queryset.select_related(*related_fields)
else:
pass
# Then, set queryset ordering.
queryset = queryset.order_by(
机智的程序员zero
- 粉丝: 2451
- 资源: 4700
最新资源
- Java源码ssm+vue框架博客系统的设计与实现+vue-毕业设计-期末大作业.zip
- ssm-vue-汽车售票网站-源码工程-29页从零开始全套图文详解-34页参考论文-27页参考答辩ppt-全套开发环境工具、文档模板、电子教程、视频教学资源分享.zip
- ssm-vue-人力资源管理系统-源码工程-29页从零开始全套图文详解-34页参考论文-27页参考答辩ppt-全套开发环境工具、文档模板、电子教程、视频教学资源分享.zip
- ssm-vue-农家乐信息平台-源码工程-29页从零开始全套图文详解-34页参考论文-27页参考答辩ppt-全套开发环境工具、文档模板、电子教程、视频教学资源分享.zip
- 基于小程序的校医务室健康服务系统源码(小程序毕业设计完整源码).zip
- Java源码ssm+vue框架大学生兼职平台的设计与开发-毕业设计-期末大作业.zip
- Java源码ssm+vue框架单位人事管理系统-毕业设计-期末大作业.zip
- Java源码ssm+vue框架大学生奖助学金发放管理系统-毕业设计-期末大作业.zip
- 环形装配线sw18可编辑全套技术资料100%好用.zip
- Java源码ssm+vue框架电能计量与客户服务管理系统vue-毕业设计-期末大作业.zip
- ssm-vue-铁岭河医院医患管理系统-源码工程-29页从零开始全套图文详解-34页参考论文-27页参考答辩ppt-全套开发环境工具、文档模板、电子教程、视频教学资源分享.zip
- 基于小程序的校园兼职系统+node源码(小程序毕业设计完整源码).zip
- ssm-vue-小学生课外知识学习网站-源码工程-29页从零开始全套图文详解-34页参考论文-27页参考答辩ppt-全套开发环境工具、文档模板、电子教程、视频教学资源分享.zip
- ssm-vue-线上旅行信息管理系统-源码工程-29页从零开始全套图文详解-34页参考论文-27页参考答辩ppt-全套开发环境工具、文档模板、电子教程、视频教学资源分享.zip
- ssm-vue-校园教务系统-源码工程-29页从零开始全套图文详解-34页参考论文-27页参考答辩ppt-全套开发环境工具、文档模板、电子教程、视频教学资源分享.zip
- ssm-vue-校园活动管理平台-源码工程-29页从零开始全套图文详解-34页参考论文-27页参考答辩ppt-全套开发环境工具、文档模板、电子教程、视频教学资源分享.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈