10 star组件之分页, search模糊查询, action批量处理

1、分页组件高阶

1、分页的class形式(有bug,请看下面的)

   

"""
自定义分页组件

"""


class Pagination(object):
    # def __init__(self, data_num, current_page, url_prefix, params, per_page=10, max_show=3):
    def __init__(self, data_num, current_page, url_prefix,per_page=10, max_show=3):
        """
        进行初始化.
        :param data_num: 数据总数
        :param current_page: 当前页
        :param url_prefix: 生成的页码的链接前缀
        :param per_page: 每页显示多少条数据
        :param max_show: 页面最多显示多少个页码
        """
        self.data_num = data_num
        self.per_page = per_page
        self.max_show = max_show
        self.url_prefix = url_prefix

        # 把页码数算出来
        self.page_num, more = divmod(data_num, per_page)
        if more:
            self.page_num += 1

        try:
            self.current_page = int(current_page)
        except Exception as e:
            self.current_page = 1
            # 如果URL传过来的页码数是负数
        if self.current_page <= 0:
            self.current_page = 1
            # 如果URL传过来的页码数超过了最大页码数
        elif self.current_page > self.page_num:
            self.current_page = self.page_num  # 默认展示最后一页

        # 页码数的一半 算出来
        self.half_show = max_show // 2

        # 页码最左边显示多少
        if self.current_page - self.half_show <= 1:
            self.page_start = 1
            self.page_end = self.max_show
        elif self.current_page + self.half_show >= self.page_num:  # 如果右边越界
            self.page_end = self.page_num
            self.page_start = self.page_num - self.max_show
        else:
            self.page_start = self.current_page - self.half_show
            # 页码最右边显示
            self.page_end = self.current_page + self.half_show

        # import copy
        # self.params = copy.deepcopy(params)  # {"page":"12","title_startwith":"py","id__gt":"5"}

    @property
    def start(self):
        # 数据从哪儿开始切
        return (self.current_page - 1) * self.per_page

    @property
    def end(self):
        # 数据切片切到哪儿
        return self.current_page * self.per_page

    def page_html(self):
        # 生成页码
        l = []
        # 加一个首页
        l.append('<li><a href="{}?page=1">首页</a></li>'.format(self.url_prefix))
        # 加一个上一页
        if self.current_page == 1:
            l.append('<li class="disabled" ><a href="#">«</a></li>'.format(self.current_page))
        else:
            l.append('<li><a href="{}?page={}">«</a></li>'.format(self.url_prefix, self.current_page - 1))


        # {"page":"12","title_startwith":"py","id__gt":"5"}  #  "page=12&title_startwith=py&id__gt=5"
        # print(self.params.urlencode())
        
        for i in range(self.page_start, self.page_end + 1):
            # self.params["page"] = i  # {"page":"7","title_startwith":"py","id__gt":"5"}  #  "page=7&title_startwith=py&id__gt=5"
            if i == self.current_page:
                tmp = '<li class="active"><a href="{0}?page={1}">{1}</a></li>'.format(self.url_prefix, i)
            else:
                # tmp = '<li><a href="{0}?{1}">{2}</a></li>'.format(self.url_prefix, self.params.urlencode(), i)
                tmp = '<li><a href="{0}?page={1}">{1}</a></li>'.format(self.url_prefix, i)
            l.append(tmp)

        # 加一个下一页
        if self.current_page == self.page_num:
            l.append('<li class="disabled"><a href="#">»</a></li>'.format(self.current_page))
        else:
            l.append('<li><a href="{}?page={}">»</a></li>'.format(self.url_prefix, self.current_page + 1))
        # 加一个尾页
        l.append('<li><a href="{}?page={}">尾页</a></li>'.format(self.url_prefix, self.page_num))
        return "".join(l)

 

from django.shortcuts import render,HttpResponse

# Create your views here.


from .models import *
def index(request):
    '''
    # 生成假数据
    book_list=[]
    for  i in range(500):
        book_obj=Book(title="book_%s"%i,price=i*i)
        book_list.append(book_obj)
    Book.objects.bulk_create(book_list)
    '''
    base_url = request.path  # /index/            # 当前url路径
    current_page=request.GET.get("page",1)      # 获取当前url中的page
    all_count=Book.objects.all().count()        # 所有book数据多少条

    # 分页器
    from app01.utils.page import  Pagination

    pagination=Pagination(all_count,int(current_page),base_url,per_page=10, max_show=11)
    # pagination=Pagination(all_count,int(current_page),base_url,request.GET,per_page=10, max_show=11)
                        # 所有数据条数,当前页的page=3,当前url路径,request.GET请求,每页显示数据,分页器最大展示几个项目

    print(pagination.start)
    print(pagination.end)

    book_list =Book.objects.all()[pagination.start:pagination.end]      # 对数据进行切片

    from django.http.request import QueryDict
    # dic = QueryDict(mutable=True)
    # dic["info"] = 123


    # print(type(request.GET))
    # request.GET["info"]=123


    import copy
    params=copy.deepcopy(request.GET)
    params["xxx"]=123

    return render(request,"index.html",locals())
Views
from django.db import models

# Create your models here.



class Book(models.Model):
    title=models.CharField(max_length=32)
    price=models.DecimalField(max_digits=8,decimal_places=2)


    def __str__(self):
        return self.title
models
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>


<ul>
    {% for foo in book_list %}
    <li>{{ foo }}</li>
    {% endfor %}

</ul>
<nav>
<ul class="pagination">
   {{ pagination.page_html|safe }}
</ul>
</nav>



</body>
</html>
index.html

 

2、如何扩展分页

 

 

 2、整合展示数据showlist类

    def list_view(self, request):
        print(self.model)  # <class 'app01.models.Book'>  用户访问的模型表

        # 构建表头
        header_list = []  # # header_list = ['选择','pk',...'操作','操作']
        for field in self.new_list_play():
            if callable(field):
                # header_list.append(field.__name__)
                val = field(self,header=True)
                header_list.append(val)
            else:
                if field == "__str__":
                    header_list.append(self.model._meta.model_name.upper())
                else:
                    val = self.model._meta.get_field(field).verbose_name    # 中文名称
                    header_list.append(val)

        # 构建表单
        data_list = self.model.objects.all()        # [obj1,obj2,...]
        new_data_list = []
        for obj in data_list:                   # Book表模型,Author表模型
            temp = []
            for field in self.new_list_play():     # ['name','age']
                if callable(field):                 # edit()  可调用的
                    val = field(self,obj)           # 直接调用edit()函数
                    print('val--------->',val)
                else:
                    val = getattr(obj,field)       # 反射  obj是实例对象,name是方法

                    # list_display_links 按钮
                    if field in self.list_display_links:
                        model_name = self.model._meta.model_name
                        app_label = self.model._meta.app_label
                        _url = reverse("%s_%s_change" % (app_label, model_name), args=(obj.pk,))
                        # print(_url)
                        val = mark_safe("<a href='%s'>%s</a>"%(_url,field))

                temp.append(val)

            new_data_list.append(temp)

        print('new_data_list',new_data_list)        # 构造数据  [['jack', 44], ['mark', 33]]

        # 构建一个addurl
        add_url = self.get_add_url()
        return render(request,'list_view.html', locals())
list_view函数形式

 

showlist类

    def list_view(self, request):
        # print(self.model)  # <class 'app01.models.Book'>  用户访问的模型表
        data_list = self.model.objects.all()        # [obj1,obj2,...]

        # 构建表头,表单
        show_list = ShowList(self,data_list)  # self=ModelSTark实例对象

        # 构建一个addurl
        add_url = self.get_add_url()
        return render(request,'list_view.html', locals())

 

class ShowList(object):
    def __init__(self,config, data_list):
        self.config = config  # MOdelStark实例对象
        self.data_list = data_list      # 数据

    def get_header(self):
        # 构建表头
        header_list = []  # # header_list = ['选择','pk',...'操作','操作']
        for field in self.config.new_list_play():
            if callable(field):
                # header_list.append(field.__name__)
                val = field(self.config,header=True)
                header_list.append(val)
            else:
                if field == "__str__":
                    header_list.append(self.config.model._meta.model_name.upper())
                else:
                    val = self.config.model._meta.get_field(field).verbose_name    # 中文名称
                    header_list.append(val)

        return header_list

    def get_body(self):
        # 构建表单
        new_data_list = []
        for obj in self.data_list:                   # Book表模型,Author表模型
            temp = []
            for field in self.config.new_list_play():     # ['name','age']
                if callable(field):                 # edit()  可调用的
                    val = field(self.config,obj)           # 直接调用edit()函数
                    print('val--------->',val)
                else:
                    val = getattr(obj,field)       # 反射  obj是实例对象,name是方法

                    # list_display_links 按钮
                    if field in self.config.list_display_links:
                        model_name = self.config.model._meta.model_name
                        app_label = self.config.model._meta.app_label
                        _url = reverse("%s_%s_change" % (app_label, model_name), args=(obj.pk,))
                        # print(_url)
                        val = mark_safe("<a href='%s'>%s</a>"%(_url,field))

                temp.append(val)

            new_data_list.append(temp)

        print('new_data_list',new_data_list)        # 构造数据  [['jack', 44], ['mark', 33]]

        return new_data_list

 

 3、stark组件之分页

 

stark/service/stark.py

# -*- coding: utf-8 -*-
# @Time    : 2018/08/17 0017 14:46
# @Author  : Venicid
from django.conf.urls import url
from django.shortcuts import HttpResponse,render,redirect

from django.utils.safestring import mark_safe
from django.urls import reverse

from stark.utils.page import Pagination
class ShowList(object):
    def __init__(self,config, data_list,request):
        self.config = config  # MOdelStark实例对象
        self.data_list = data_list      # 数据
        self.request =request

        # 分页
        data_count = self.data_list.count()
        current_page = int(self.request.GET.get('page',1))
        base_path = self.request.path
        self.pagination = Pagination(current_page,data_count,base_path,self.request.GET,per_page_num=1, pager_count=11,)

        # 分页后的数据
        self.page_data = self.data_list[self.pagination.start:self.pagination.end]

    def get_header(self):
        # 构建表头
        header_list = []  # # header_list = ['选择','pk',...'操作','操作']
        for field in self.config.new_list_play():
            if callable(field):
                # header_list.append(field.__name__)
                val = field(self.config,header=True)
                header_list.append(val)
            else:
                if field == "__str__":
                    header_list.append(self.config.model._meta.model_name.upper())
                else:
                    val = self.config.model._meta.get_field(field).verbose_name    # 中文名称
                    header_list.append(val)

        return header_list

    def get_body(self):
        # 构建表单
        new_data_list = []
        for obj in self.page_data:    #分页后的数据               # Book表模型,Author表模型
            temp = []
            for field in self.config.new_list_play():     # ['name','age']
                if callable(field):                 # edit()  可调用的
                    val = field(self.config,obj)           # 直接调用edit()函数
                    print('val--------->',val)
                else:
                    val = getattr(obj,field)       # 反射  obj是实例对象,name是方法

                    # list_display_links 按钮
                    if field in self.config.list_display_links:
                        model_name = self.config.model._meta.model_name
                        app_label = self.config.model._meta.app_label
                        _url = reverse("%s_%s_change" % (app_label, model_name), args=(obj.pk,))
                        # print(_url)
                        val = mark_safe("<a href='%s'>%s</a>"%(_url,field))

                temp.append(val)

            new_data_list.append(temp)

        print('new_data_list',new_data_list)        # 构造数据  [['jack', 44], ['mark', 33]]

        return new_data_list


class ModelStark(object):
    list_display = ["__str__"]  # 子类中没有,直接用父类自己的
    list_display_links = []

    modelform_class = []

    def __init__(self,model, site):
        self.model = model
        self.site = site

    # 增删改查url
    def get_add_url(self):
        model_name = self.model._meta.model_name
        app_label = self.model._meta.app_label
        _url = reverse("%s_%s_add" %(app_label,model_name))
        return _url

    def get_list_url(self):
        model_name = self.model._meta.model_name
        app_label = self.model._meta.app_label
        _url = reverse("%s_%s_list" %(app_label,model_name))
        return _url


    # 复选框,编辑,删除
    def checkbox(self,obj=None, header=False):
        if header:
            return mark_safe("<input id='choice' type='checkbox'>")
        return mark_safe("<input class='choice_item' type='checkbox'>")


    def edit(self,obj=None, header=False):
        if header:
            return "操作"
        # 方案1:固定url
        # return mark_safe("<a href=/stark/app01/userinfo/%s/change>编辑</a>")
        # 方案2:拼接url
        # return mark_safe("<a href='%s/change'>编辑</a>")

        # 方案3:反向解析
        model_name = self.model._meta.model_name
        app_label = self.model._meta.app_label
        _url = reverse("%s_%s_change"%(app_label,model_name),args=(obj.pk,))
        # print("_url",_url)
        return mark_safe("<a href='%s'>编辑</a>"%_url)


    def deletes(self,obj=None, header=False):
        if header:
            return "操作"
        model_name = self.model._meta.model_name
        app_label = self.model._meta.app_label
        _url = reverse("%s_%s_delete"%(app_label,model_name),args=(obj.pk,))
        return mark_safe("<a href='%s'>删除</a>"%_url)



    # ModelForm组件渲染  list、增、删、改页面
    def get_modelform_class(self):
        """ModelForm组件"""
        if not self.modelform_class:
            from django.forms import ModelForm
            class ModelFormDemo(ModelForm):
                class Meta:
                    model = self.model
                    fields = "__all__"
            return ModelFormDemo
        else:
            return self.modelform_class

    def new_list_play(self):
        """构建 ['checkbox','pk', 'name', 'age', edit,'delete']"""
        temp = []
        temp.append(ModelStark.checkbox)
        temp.extend(self.list_display)
        if not self.list_display_links:
            temp.append(ModelStark.edit)
        temp.append(ModelStark.deletes)
        return temp

    def list_view(self, request):
        # print(self.model)  # <class 'app01.models.Book'>  用户访问的模型表
        data_list = self.model.objects.all()        # [obj1,obj2,...]

        # 构建表头,表单
        show_list = ShowList(self,data_list,request)  # self=ModelSTark实例对象

        # 构建一个addurl
        add_url = self.get_add_url()
        return render(request,'list_view.html', locals())


    def add_view(self, request):
        ModelFormDemo=self.get_modelform_class()
        form = ModelFormDemo()
        if request.method == "POST":
            form = ModelFormDemo(request.POST)
            if form.is_valid():
                form.save()
                return redirect(self.get_list_url())

        return render(request, "add_view.html",locals())

    def delete_view(self, request, id):
        url = self.get_list_url()
        if request.method == "POST":
            self.model.objects.filter(pk=id).delete()
            return redirect(url)
        return render(request, "delete_view.html", locals())

    def change_view(self, request, id):
        edit_obj = self.model.objects.filter(pk=id).first()

        ModelFormDemo=self.get_modelform_class()
        form = ModelFormDemo(instance=edit_obj)
        if request.method == "POST":
            form = ModelFormDemo(request.POST,instance=edit_obj)
            if form.is_valid():
                form.save()
                return redirect(self.get_list_url())

        return render(request, "change_view.html",locals())


    #构造 add/delete/change
    def get_urls2(self):
        model_name = self.model._meta.model_name
        app_label = self.model._meta.app_label

        temp = []
        temp.append(url(r'^$', self.list_view, name='%s_%s_list'%(app_label,model_name)))
        temp.append(url(r'^add/', self.add_view, name='%s_%s_add'%(app_label,model_name)))
        temp.append(url(r'^(\d+)/delete/', self.delete_view, name='%s_%s_delete'%(app_label,model_name)))
        temp.append(url(r'^(\d+)/change/', self.change_view, name='%s_%s_change'%(app_label,model_name)))

        return temp

    @property
    def urls2(self):

        return self.get_urls2(), None, None


class StarkSite(object):
    """site单例类"""
    def __init__(self):
        self._registry = {}

    def register(self,model, stark_class=None):
        """注册"""
        if not stark_class:
            stark_class = ModelStark

        self._registry[model] = stark_class(model,self)

    def get_urls(self):
        """构造一层urls app01/book"""
        temp = []
        for model, stark_class_obj in self._registry.items():
            print(model, 'stark_clas_obj', stark_class_obj)  # 不同的model模型表
            """
             <class 'app01.models.UserInfo'> ----> <app01.starkadmin.UserConfig object at 0x00000072DDB65198>
             <class 'app01.models.Book'> ----> <stark.service.stark.ModelStark object at 0x00000072DDB65240>
             """

            app_label = model._meta.app_label     # app01
            model_name = model._meta.model_name   # book
            # temp.append(url(r'^%s/%s'%(app_label, model_name),([],None,None)))
            temp.append(url(r'^%s/%s/'%(app_label, model_name),stark_class_obj.urls2))
            """
               path('app01/userinfo/',UserConfig(Userinfo,site).urls2),
               path('app01/book/',ModelStark(Book,site).urls2),
            """


        return temp

    @property
    def urls(self):

        # return [],None,None
        return self.get_urls(),None,None

site = StarkSite()   # 单例对象
View Code

 

 

stark/utils/page.py(自定义分页,老师版本)

"""
自定义分页组件
"""


class Pagination(object):
    def __init__(self, current_page, all_count, base_url,params, per_page_num=8, pager_count=11, ):
        """
        封装分页相关数据
        :param current_page: 当前页
        :param all_count:    数据库中的数据总条数
        :param per_page_num: 每页显示的数据条数
        :param base_url: 分页中显示的URL前缀
        :param pager_count:  最多显示的页码个数
        """

        try:
            current_page = int(current_page)
        except Exception as e:
            current_page = 1

        if current_page < 1:
            current_page = 1

        self.current_page = current_page

        self.all_count = all_count
        self.per_page_num = per_page_num

        self.base_url = base_url

        # 总页码
        all_pager, tmp = divmod(all_count, per_page_num)
        if tmp:
            all_pager += 1
        self.all_pager = all_pager

        self.pager_count = pager_count  # 最多显示页码数
        self.pager_count_half = int((pager_count - 1) / 2)

        import copy
        params = copy.deepcopy(params)
        params._mutable = True
        self.params = params  # self.params : {"page":77,"title":"python","nid":1}


    @property
    def start(self):
        return (self.current_page - 1) * self.per_page_num


    @property
    def end(self):
        return self.current_page * self.per_page_num


    def page_html(self):
        # 如果总页码 < 11个:
        if self.all_pager <= self.pager_count:
            pager_start = 1
            pager_end = self.all_pager + 1
        # 总页码  > 11
        else:
            # 当前页如果<=页面上最多显示(11-1)/2个页码
            if self.current_page <= self.pager_count_half:
                pager_start = 1
                pager_end = self.pager_count + 1

            # 当前页大于5
            else:
                # 页码翻到最后
                if (self.current_page + self.pager_count_half) > self.all_pager:
                    pager_start = self.all_pager - self.pager_count + 1
                    pager_end = self.all_pager + 1

                else:
                    pager_start = self.current_page - self.pager_count_half
                    pager_end = self.current_page + self.pager_count_half + 1

        page_html_list = []
        self.params["page"] = 1
        first_page = '<li><a href="%s?%s">首页</a></li>' % (self.base_url, self.params.urlencode(),)
        page_html_list.append(first_page)

        if self.current_page <= 1:
            prev_page = '<li class="disabled"><a href="#">上一页</a></li>'
        else:
            self.params["page"] = self.current_page - 1
            prev_page = '<li><a href="%s?%s">上一页</a></li>' % (self.base_url, self.params.urlencode(),)

        page_html_list.append(prev_page)

        for i in range(pager_start, pager_end):
            #  self.params  : {"page":77,"title":"python","nid":1}

            self.params["page"] = i  # {"page":72,"title":"python","nid":1}
            if i == self.current_page:
                temp = '<li class="active"><a href="%s?%s">%s</a></li>' % (self.base_url, self.params.urlencode(), i,)
            else:
                temp = '<li><a href="%s?%s">%s</a></li>' % (self.base_url, self.params.urlencode(), i,)
            page_html_list.append(temp)

        if self.current_page >= self.all_pager:
            next_page = '<li class="disabled"><a href="#">下一页</a></li>'
        else:
            self.params["page"] = self.current_page + 1
            next_page = '<li><a href="%s?%s">下一页</a></li>' % (self.base_url, self.params.urlencode(),)
        page_html_list.append(next_page)

        self.params["page"] = self.all_pager
        last_page = '<li><a href="%s?%s">尾页</a></li>' % (self.base_url, self.params.urlencode(),)
        page_html_list.append(last_page)

        return ''.join(page_html_list)

 

list_view.html

 

{% extends 'base.html' %}

{% block title %}
    <title>list页面</title>
{% endblock %}

{% block header %}
    <h3>list页面</h3>
{% endblock %}
{% block content %}
    <a class="btn btn-primary" href="{{ add_url }}">添加数据</a>
    <table class="table table-bordered table-striped">
        <tr>
            {% for header in show_list.get_header %}
                {#            {% for header in header_list %}#}
                <th>{{ header }}</th>
            {% endfor %}
        </tr>

        {% for data in show_list.get_body %}
            {#        {% for data in new_data_list %}#}
            <tr>
                {% for item in data %}
                    <td>{{ item }}</td>
                {% endfor %}

            </tr>
        {% endfor %}
    </table>
    <nav>
        <ul class="pagination">
            {{ show_list.pagination.page_html|safe }}
        </ul>
    </nav>

{% endblock %}


{% block javascript %}
    <script type="text/javascript">
        $('#choice').click(function () {
            if ($(this).prop('checked')) {   //对象自身属性中是否具有指定的属性
                $('.choice_item').prop("checked", true)
            } else {
                $('.choice_item').prop("checked", false)
            }
        })
    </script>
{% endblock %}
View Code

 

 

3、stark组件之search模糊查询

1、orm中的模糊查询

 2、orm中的Q查询 与或非

3、stark组件之模糊查询

 

 

 def list_view(self, request):
        # print(self.model)  # <class 'app01.models.Book'>  用户访问的模型表

        # 模糊查询过滤
        key_word = request.GET.get("q")
        from django.db.models import Q   # 与或非
        search_connection = Q()
        if key_word:
            search_connection.connector = "or"
            for search_field in self.search_fields:
                search_connection.children.append((search_field+"__contains", key_word))

        data_list = self.model.objects.all().filter(search_connection)


        #按照showlist展示页面, 构建表头,表单
        show_list = ShowList(self,data_list,request)  # self=ModelSTark实例对象

        # 构建一个查看addurl
        add_url = self.get_add_url()
        return render(request,'list_view.html', locals())

4、解耦

 

 

如果没有在starkadmin定义search_fields字段,就不显示search按钮

 

 6、代码

# -*- coding: utf-8 -*-
# @Time    : 2018/08/17 0017 14:46
# @Author  : Venicid
from django.conf.urls import url
from django.shortcuts import HttpResponse,render,redirect

from django.utils.safestring import mark_safe
from django.urls import reverse

from stark.utils.page import Pagination
class ShowList(object):
    def __init__(self,config, data_list,request):
        self.config = config  # MOdelStark实例对象
        self.data_list = data_list      # 数据
        self.request =request

        # 分页
        data_count = self.data_list.count()
        current_page = int(self.request.GET.get('page',1))
        base_path = self.request.path
        self.pagination = Pagination(current_page,data_count,base_path,self.request.GET,per_page_num=11, pager_count=11,)

        # 分页后的数据
        self.page_data = self.data_list[self.pagination.start:self.pagination.end]

    def get_header(self):
        # 构建表头
        header_list = []  # # header_list = ['选择','pk',...'操作','操作']
        for field in self.config.new_list_play():
            if callable(field):
                # header_list.append(field.__name__)
                val = field(self.config,header=True)
                header_list.append(val)
            else:
                if field == "__str__":
                    header_list.append(self.config.model._meta.model_name.upper())
                else:
                    val = self.config.model._meta.get_field(field).verbose_name    # 中文名称
                    header_list.append(val)

        return header_list

    def get_body(self):
        # 构建表单
        new_data_list = []
        for obj in self.page_data:    #分页后的数据               # Book表模型,Author表模型
            temp = []
            for field in self.config.new_list_play():     # ['name','age']
                if callable(field):                 # edit()  可调用的
                    val = field(self.config,obj)           # 直接调用edit()函数
                    print('val--------->',val)
                else:
                    val = getattr(obj,field)       # 反射  obj是实例对象,name是方法

                    # list_display_links 按钮
                    if field in self.config.list_display_links:
                        model_name = self.config.model._meta.model_name
                        app_label = self.config.model._meta.app_label
                        _url = reverse("%s_%s_change" % (app_label, model_name), args=(obj.pk,))
                        # print(_url)
                        val = mark_safe("<a href='%s'>%s</a>"%(_url,field))

                temp.append(val)

            new_data_list.append(temp)

        print('new_data_list',new_data_list)        # 构造数据  [['jack', 44], ['mark', 33]]

        return new_data_list


class ModelStark(object):
    list_display = ["__str__"]  # 子类中没有,直接用父类自己的
    list_display_links = []
    modelform_class = []
    search_fields = []  # 模糊查询字段

    def __init__(self,model, site):
        self.model = model
        self.site = site

    # 增删改查url
    def get_add_url(self):
        model_name = self.model._meta.model_name
        app_label = self.model._meta.app_label
        _url = reverse("%s_%s_add" %(app_label,model_name))
        return _url

    def get_list_url(self):
        model_name = self.model._meta.model_name
        app_label = self.model._meta.app_label
        _url = reverse("%s_%s_list" %(app_label,model_name))
        return _url


    # 复选框,编辑,删除
    def checkbox(self,obj=None, header=False):
        if header:
            return mark_safe("<input id='choice' type='checkbox'>")
        return mark_safe("<input class='choice_item' type='checkbox'>")


    def edit(self,obj=None, header=False):
        if header:
            return "操作"
        # 方案1:固定url
        # return mark_safe("<a href=/stark/app01/userinfo/%s/change>编辑</a>")
        # 方案2:拼接url
        # return mark_safe("<a href='%s/change'>编辑</a>")

        # 方案3:反向解析
        model_name = self.model._meta.model_name
        app_label = self.model._meta.app_label
        _url = reverse("%s_%s_change"%(app_label,model_name),args=(obj.pk,))
        # print("_url",_url)
        return mark_safe("<a href='%s'>编辑</a>"%_url)


    def deletes(self,obj=None, header=False):
        if header:
            return "操作"
        model_name = self.model._meta.model_name
        app_label = self.model._meta.app_label
        _url = reverse("%s_%s_delete"%(app_label,model_name),args=(obj.pk,))
        return mark_safe("<a href='%s'>删除</a>"%_url)



    # ModelForm组件渲染  list、增、删、改页面
    def get_modelform_class(self):
        """ModelForm组件"""
        if not self.modelform_class:
            from django.forms import ModelForm
            class ModelFormDemo(ModelForm):
                class Meta:
                    model = self.model
                    fields = "__all__"
            return ModelFormDemo
        else:
            return self.modelform_class

    def new_list_play(self):
        """构建 ['checkbox','pk', 'name', 'age', edit,'delete']"""
        temp = []
        temp.append(ModelStark.checkbox)
        temp.extend(self.list_display)
        if not self.list_display_links:
            temp.append(ModelStark.edit)
        temp.append(ModelStark.deletes)
        return temp


    '''
    def list_view(self,request):
        ret1 = self.model.objects.filter(title__startswith='py')
        ret2 = self.model.objects.filter(price__in=[11,22,33,44,55])
        ret3 = self.model.objects.filter(price__range=[10,20])
        ret4 = self.model.objects.filter(title__contains='O')
        ret5 = self.model.objects.filter(title__icontains='O')
        return HttpResponse("过滤成功")
    '''

    def get_search_condition(self,request):
        """search模糊查询"""
        key_word = request.GET.get("q",'')
        self.key_word = key_word
        from django.db.models import Q   # 与或非
        search_connection = Q()
        if key_word:
            search_connection.connector = "or"
            for search_field in self.search_fields:
                search_connection.children.append((search_field+"__contains", key_word))

        return search_connection

    def list_view(self, request):
        # 获取search的Q对象
        search_connection = self.get_search_condition(request)

        # 筛选获取当前表所有数据
        data_list = self.model.objects.all().filter(search_connection)

        #按照showlist展示页面, 构建表头,表单
        show_list = ShowList(self,data_list,request)  # self=ModelSTark实例对象

        # 构建一个查看addurl
        add_url = self.get_add_url()
        return render(request,'list_view.html', locals())


    def add_view(self, request):
        ModelFormDemo=self.get_modelform_class()
        form = ModelFormDemo()
        if request.method == "POST":
            form = ModelFormDemo(request.POST)
            if form.is_valid():
                form.save()
                return redirect(self.get_list_url())

        return render(request, "add_view.html",locals())

    def delete_view(self, request, id):
        url = self.get_list_url()
        if request.method == "POST":
            self.model.objects.filter(pk=id).delete()
            return redirect(url)
        return render(request, "delete_view.html", locals())

    def change_view(self, request, id):
        edit_obj = self.model.objects.filter(pk=id).first()

        ModelFormDemo=self.get_modelform_class()
        form = ModelFormDemo(instance=edit_obj)
        if request.method == "POST":
            form = ModelFormDemo(request.POST,instance=edit_obj)
            if form.is_valid():
                form.save()
                return redirect(self.get_list_url())

        return render(request, "change_view.html",locals())


    #构造 add/delete/change
    def get_urls2(self):
        model_name = self.model._meta.model_name
        app_label = self.model._meta.app_label

        temp = []
        temp.append(url(r'^$', self.list_view, name='%s_%s_list'%(app_label,model_name)))
        temp.append(url(r'^add/', self.add_view, name='%s_%s_add'%(app_label,model_name)))
        temp.append(url(r'^(\d+)/delete/', self.delete_view, name='%s_%s_delete'%(app_label,model_name)))
        temp.append(url(r'^(\d+)/change/', self.change_view, name='%s_%s_change'%(app_label,model_name)))

        return temp

    @property
    def urls2(self):

        return self.get_urls2(), None, None


class StarkSite(object):
    """site单例类"""
    def __init__(self):
        self._registry = {}

    def register(self,model, stark_class=None):
        """注册"""
        if not stark_class:
            stark_class = ModelStark

        self._registry[model] = stark_class(model,self)

    def get_urls(self):
        """构造一层urls app01/book"""
        temp = []
        for model, stark_class_obj in self._registry.items():
            print(model, 'stark_clas_obj', stark_class_obj)  # 不同的model模型表
            """
             <class 'app01.models.UserInfo'> ----> <app01.starkadmin.UserConfig object at 0x00000072DDB65198>
             <class 'app01.models.Book'> ----> <stark.service.stark.ModelStark object at 0x00000072DDB65240>
             """

            app_label = model._meta.app_label     # app01
            model_name = model._meta.model_name   # book
            # temp.append(url(r'^%s/%s'%(app_label, model_name),([],None,None)))
            temp.append(url(r'^%s/%s/'%(app_label, model_name),stark_class_obj.urls2))
            """
               path('app01/userinfo/',UserConfig(Userinfo,site).urls2),
               path('app01/book/',ModelStark(Book,site).urls2),
            """


        return temp

    @property
    def urls(self):

        # return [],None,None
        return self.get_urls(),None,None

site = StarkSite()   # 单例对象
stark/service/stark.py
from stark.service import stark
from .models import *
from django.forms import ModelForm

class BookModelForm(ModelForm):
    class Meta:
        model = Book
        fields = "__all__"

        labels = {
            "authors":"作者",
            "publishDate":"出版日期",
        }

class BookConfig(stark.ModelStark):
    list_display = ['nid', 'title', 'price']
    modelform_class = BookModelForm
    # search_fields = ['title','price']

class AuthorConfig(stark.ModelStark):
    list_display = ['nid', 'name', 'age']
    list_display_links = ['name','age']



stark.site.register(Book,BookConfig)
stark.site.register(Publish)
stark.site.register(Author,AuthorConfig)
stark.site.register(AuthorDetail)

print(stark.site._registry)

"""
{<class 'app01.models.Book'>: <stark.service.stark.ModelStark object at 0x0000003AA7439630>,
<class 'app01.models.Publish'>: <stark.service.stark.ModelStark object at 0x0000003AA7439668>,
<class 'app01.models.Author'>: <stark.service.stark.ModelStark object at 0x0000003AA74396A0>,
<class 'app01.models.AuthorDetail'>: <stark.service.stark.ModelStark object at 0x0000003AA7439940>}
"""
starkadmin.py
{% extends 'base.html' %}

{% block title %}
    <title>list页面</title>
{% endblock %}

{% block header %}
    <h3>list页面</h3>
{% endblock %}
{% block content %}
    <a class="btn btn-primary" href="{{ add_url }}">添加数据</a>
    {% if show_list.config.search_fields %}
        <form action="" method="get" class="pull-right">
            <input type="text" name="q" value="{{ show_list.config.key_word }}">
            <button>submit</button>
        </form>
    {% endif %}


    <table class="table table-bordered table-striped">
        <tr>
            {% for header in show_list.get_header %}
                {#            {% for header in header_list %}#}
                <th>{{ header }}</th>
            {% endfor %}
        </tr>

        {% for data in show_list.get_body %}
            {#        {% for data in new_data_list %}#}
            <tr>
                {% for item in data %}
                    <td>{{ item }}</td>
                {% endfor %}

            </tr>
        {% endfor %}
    </table>
    <nav>
        <ul class="pagination">
            {{ show_list.pagination.page_html|safe }}
        </ul>
    </nav>

{% endblock %}


{% block javascript %}
    <script type="text/javascript">
        $('#choice').click(function () {
            if ($(this).prop('checked')) {   //对象自身属性中是否具有指定的属性
                $('.choice_item').prop("checked", true)
            } else {
                $('.choice_item').prop("checked", false)
            }
        })
    </script>
{% endblock %}
list_view.html

 

4、action批量处理数据

0、必备知识

1、admin的批量初始化

 

 

3、starkadmin之actions

4、构建actions数据

 

5、前端的按钮checkbox,提交数据

 6、post提交处理 数据

 

 

6、starkadmin.py

from django.shortcuts import HttpResponse
from stark.service import stark
from .models import *
from django.forms import ModelForm

class AuthorConfig(stark.ModelStark):
    list_display = ['nid', 'name', 'age']
    list_display_links = ['name','age']


class BookModelForm(ModelForm):
    class Meta:
        model = Book
        fields = "__all__"

        labels = {
            "authors":"作者",
            "publishDate":"出版日期",
        }

class BookConfig(stark.ModelStark):
    list_display = ['nid', 'title', 'price']
    modelform_class = BookModelForm
    search_fields = ['title','price']

    # 批量修改数据
    def patch_init(self,request,queryset):
        queryset.update(price=111)

        # return HttpResponse("批量初始化OK")

    patch_init.short_description = "批量初始化"

    actions = [patch_init]


stark.site.register(Book,BookConfig)
stark.site.register(Publish)
stark.site.register(Author,AuthorConfig)
stark.site.register(AuthorDetail)

print(stark.site._registry)

 

7、stark/service /stark

# -*- coding: utf-8 -*-
# @Time    : 2018/08/17 0017 14:46
# @Author  : Venicid
from django.conf.urls import url
from django.shortcuts import HttpResponse,render,redirect

from django.utils.safestring import mark_safe
from django.urls import reverse

from stark.utils.page import Pagination
class ShowList(object):
    def __init__(self,config, data_list,request):
        self.config = config  # MOdelStark实例对象
        self.data_list = data_list      # 数据
        self.request =request

        # 分页
        data_count = self.data_list.count()
        current_page = int(self.request.GET.get('page',1))
        base_path = self.request.path
        self.pagination = Pagination(current_page,data_count,base_path,self.request.GET,per_page_num=11, pager_count=11,)

        # 分页后的数据
        self.page_data = self.data_list[self.pagination.start:self.pagination.end]

        # actions 批量初始化,字段
        self.actions = self.config.actions # [patch_init]
        # 构建数据[{'name':'path_init',"desc":'xxxxx'}]


    def get_action_list(self):
        """action批量初始化,构架数据"""
        temp = []
        for action in self.actions:
            temp.append(
                {'name':action.__name__,                # class的类名
                 "desc":action.short_description        # class的属性
                 }
            )
        return temp

    def get_header(self):
        # 构建表头
        header_list = []  # # header_list = ['选择','pk',...'操作','操作']
        for field in self.config.new_list_play():
            if callable(field):
                # header_list.append(field.__name__)
                val = field(self.config, header=True)
                header_list.append(val)
            else:
                if field == "__str__":
                    header_list.append(self.config.model._meta.model_name.upper())
                else:
                    val = self.config.model._meta.get_field(field).verbose_name    # 中文名称
                    header_list.append(val)

        return header_list

    def get_body(self):
        # 构建表单
        new_data_list = []
        for obj in self.page_data:    #分页后的数据               # Book表模型,Author表模型
            temp = []
            for field in self.config.new_list_play():     # ['name','age']
                if callable(field):                 # edit()  可调用的
                    print(obj,99999999999999999)
                    val = field(self.config,obj)           # 直接调用edit()函数
                    print('val--------->',val)
                else:
                    val = getattr(obj,field)       # 反射  obj是实例对象,name是方法

                    # list_display_links 按钮
                    if field in self.config.list_display_links:
                        model_name = self.config.model._meta.model_name
                        app_label = self.config.model._meta.app_label
                        _url = reverse("%s_%s_change" % (app_label, model_name), args=(obj.pk,))
                        # print(_url)
                        val = mark_safe("<a href='%s'>%s</a>"%(_url,field))

                temp.append(val)

            new_data_list.append(temp)

        print('new_data_list',new_data_list)        # 构造数据  [['jack', 44], ['mark', 33]]

        return new_data_list


class ModelStark(object):
    list_display = ["__str__"]  # 子类中没有,直接用父类自己的
    list_display_links = []
    modelform_class = []
    search_fields = []  # 模糊查询字段
    actions = []

    def __init__(self,model, site):
        self.model = model
        self.site = site

    # 增删改查url
    def get_add_url(self):
        model_name = self.model._meta.model_name
        app_label = self.model._meta.app_label
        _url = reverse("%s_%s_add" %(app_label,model_name))
        return _url

    def get_list_url(self):
        model_name = self.model._meta.model_name
        app_label = self.model._meta.app_label
        _url = reverse("%s_%s_list" %(app_label,model_name))
        return _url


    # 复选框,编辑,删除
    def checkbox(self,obj=None, header=False):
        if header:
            return mark_safe("<input id='choice' type='checkbox'>")
        return mark_safe("<input class='choice_item' type='checkbox' name='selected_pk' value='%s'>"%obj.pk)


    def edit(self,obj=None, header=False):
        if header:
            return "操作"
        # 方案1:固定url
        # return mark_safe("<a href=/stark/app01/userinfo/%s/change>编辑</a>")
        # 方案2:拼接url
        # return mark_safe("<a href='%s/change'>编辑</a>")

        # 方案3:反向解析
        model_name = self.model._meta.model_name
        app_label = self.model._meta.app_label
        _url = reverse("%s_%s_change"%(app_label,model_name),args=(obj.pk,))
        # print("_url",_url)
        return mark_safe("<a href='%s'>编辑</a>"%_url)


    def deletes(self,obj=None, header=False):
        if header:
            return "操作"
        model_name = self.model._meta.model_name
        app_label = self.model._meta.app_label
        _url = reverse("%s_%s_delete"%(app_label,model_name),args=(obj.pk,))
        return mark_safe("<a href='%s'>删除</a>"%_url)



    # ModelForm组件渲染  list、增、删、改页面
    def get_modelform_class(self):
        """ModelForm组件"""
        if not self.modelform_class:
            from django.forms import ModelForm
            class ModelFormDemo(ModelForm):
                class Meta:
                    model = self.model
                    fields = "__all__"
            return ModelFormDemo
        else:
            return self.modelform_class

    def new_list_play(self):
        """构建 ['checkbox','pk', 'name', 'age', edit,'delete']"""
        temp = []
        temp.append(ModelStark.checkbox)
        temp.extend(self.list_display)
        if not self.list_display_links:
            temp.append(ModelStark.edit)
        temp.append(ModelStark.deletes)
        return temp


    '''
    def list_view(self,request):
        ret1 = self.model.objects.filter(title__startswith='py')
        ret2 = self.model.objects.filter(price__in=[11,22,33,44,55])
        ret3 = self.model.objects.filter(price__range=[10,20])
        ret4 = self.model.objects.filter(title__contains='O')
        ret5 = self.model.objects.filter(title__icontains='O')
        return HttpResponse("过滤成功")
    '''

    def get_search_condition(self,request):
        """search模糊查询"""
        key_word = request.GET.get("q",'')
        self.key_word = key_word
        from django.db.models import Q   # 与或非
        search_connection = Q()
        if key_word:
            search_connection.connector = "or"
            for search_field in self.search_fields:
                search_connection.children.append((search_field+"__contains", key_word))

        return search_connection

    def list_view(self, request):
        if request.method == 'POST':
            print('post',request.POST)
            action = request.POST.get("action")                     # action': ['patch_init'],
            if action:
                selected_pk = request.POST.getlist('selected_pk')       # 'selected_pk': ['5']}>
                action_func = getattr(self,action)  # 反射查询 action

                queryset = self.model.objects.filter(pk__in=selected_pk)        # 查询
                ret = action_func(request,queryset)    # 执行action()
                # return ret


        # 获取search的Q对象
        search_connection = self.get_search_condition(request)

        # 筛选获取当前表所有数据
        data_list = self.model.objects.all().filter(search_connection)

        #按照showlist展示页面, 构建表头,表单
        show_list = ShowList(self,data_list,request)  # self=ModelSTark实例对象

        # 构建一个查看addurl
        add_url = self.get_add_url()
        return render(request,'list_view.html', locals())


    def add_view(self, request):
        ModelFormDemo=self.get_modelform_class()
        form = ModelFormDemo()
        if request.method == "POST":
            form = ModelFormDemo(request.POST)
            if form.is_valid():
                form.save()
                return redirect(self.get_list_url())

        return render(request, "add_view.html",locals())

    def delete_view(self, request, id):
        url = self.get_list_url()
        if request.method == "POST":
            self.model.objects.filter(pk=id).delete()
            return redirect(url)
        return render(request, "delete_view.html", locals())

    def change_view(self, request, id):
        edit_obj = self.model.objects.filter(pk=id).first()

        ModelFormDemo=self.get_modelform_class()
        form = ModelFormDemo(instance=edit_obj)
        if request.method == "POST":
            form = ModelFormDemo(request.POST,instance=edit_obj)
            if form.is_valid():
                form.save()
                return redirect(self.get_list_url())

        return render(request, "change_view.html",locals())


    #构造 add/delete/change
    def get_urls2(self):
        model_name = self.model._meta.model_name
        app_label = self.model._meta.app_label

        temp = []
        temp.append(url(r'^$', self.list_view, name='%s_%s_list'%(app_label,model_name)))
        temp.append(url(r'^add/', self.add_view, name='%s_%s_add'%(app_label,model_name)))
        temp.append(url(r'^(\d+)/delete/', self.delete_view, name='%s_%s_delete'%(app_label,model_name)))
        temp.append(url(r'^(\d+)/change/', self.change_view, name='%s_%s_change'%(app_label,model_name)))

        return temp

    @property
    def urls2(self):

        return self.get_urls2(), None, None


class StarkSite(object):
    """site单例类"""
    def __init__(self):
        self._registry = {}

    def register(self,model, stark_class=None):
        """注册"""
        if not stark_class:
            stark_class = ModelStark

        self._registry[model] = stark_class(model,self)

    def get_urls(self):
        """构造一层urls app01/book"""
        temp = []
        for model, stark_class_obj in self._registry.items():
            print(model, 'stark_clas_obj', stark_class_obj)  # 不同的model模型表
            """
             <class 'app01.models.UserInfo'> ----> <app01.starkadmin.UserConfig object at 0x00000072DDB65198>
             <class 'app01.models.Book'> ----> <stark.service.stark.ModelStark object at 0x00000072DDB65240>
             """

            app_label = model._meta.app_label     # app01
            model_name = model._meta.model_name   # book
            # temp.append(url(r'^%s/%s'%(app_label, model_name),([],None,None)))
            temp.append(url(r'^%s/%s/'%(app_label, model_name),stark_class_obj.urls2))
            """
               path('app01/userinfo/',UserConfig(Userinfo,site).urls2),
               path('app01/book/',ModelStark(Book,site).urls2),
            """


        return temp

    @property
    def urls(self):

        # return [],None,None
        return self.get_urls(),None,None

site = StarkSite()   # 单例对象
View Code

 

8、list_view.html

{% extends 'base.html' %}

{% block title %}
    <title>list页面</title>
{% endblock %}

{% block header %}
    <h3>list页面</h3>
{% endblock %}
{% block content %}
    <p><a class="btn btn-primary" href="{{ add_url }}">添加数据</a></p>
    {% if show_list.config.search_fields %}
        <form action="" method="get" class="pull-right">
            <input type="text" name="q" value="{{ show_list.config.key_word }}">
            <button>submit</button>
        </form>
    {% endif %}


    <form action="" method="post">
        {% csrf_token %}

        {% if show_list.get_action_list %}
            <select name="action" id="" style="display: inline-block;width: 200px;margin: 8px 8px 8px 0;height: 25px">
                {% for item in show_list.get_action_list %}
                    <option value="">-------</option>
                    <option value="{{ item.name }}">{{ item.desc }}</option>
                {% endfor %}
            </select>
            <button type="submit" class="btn btn-default">Go</button>

        {% endif %}


        <table class="table table-bordered table-striped">
            <tr>
                {% for header in show_list.get_header %}
                    {#            {% for header in header_list %}#}
                    <th>{{ header }}</th>
                {% endfor %}
            </tr>

            {% for data in show_list.get_body %}
                {#        {% for data in new_data_list %}#}
                <tr>
                    {% for item in data %}
                        <td>{{ item }}</td>
                    {% endfor %}

                </tr>
            {% endfor %}
        </table>
    </form>

    <nav>
        <ul class="pagination">
            {{ show_list.pagination.page_html|safe }}
        </ul>
    </nav>

{% endblock %}


{% block javascript %}
    <script type="text/javascript">
        $('#choice').click(function () {
            if ($(this).prop('checked')) {   //对象自身属性中是否具有指定的属性
                $('.choice_item').prop("checked", true)
            } else {
                $('.choice_item').prop("checked", false)
            }
        })
    </script>
{% endblock %}
View Code

 

4、总结

1、分页知识点

1.分页
{{ showlist.pagination.page_html|safe }}

2.page.py
class Pagination(object):
def __init__(self, current_page, all_count, base_url,params, per_page_num=8, pager_count=11):
"""
封装分页相关数据
:param current_page: 当前页
:param all_count: 数据库中的数据总条数
:param per_page_num: 每页显示的数据条数
:param base_url: 分页中显示的URL前缀
:param pager_count: 最多显示的页码个数
:param params: ? 后面携带得参数 request.GET
"""

...

注意:翻页时,http://127.0.0.1:8090/stark/app01/publish/?page=2&name=alice&age=18
每页需带上之前的参数。

import copy
params = copy.deepcopy(params)
params._mutable = True
self.params = params # self.params : {"page":77,"title":"python","nid":1}

self.params["page"] = i
self.params.urlencode() 将{"name":"alice","age":18} 转换成 name=alice&age=18

temp = '<li><a href="%s?%s">%s</a></li>' % (self.base_url, self.params.urlencode(), i,)

3.list_view 视图函数
表头,表数据,分页... 内容太多,封装在一个类里面专门用来展示数据。
# 展示数据
showlist = ShowList(self, data_list, request)
class ShowList(object):
def __init__(self):
pass

def get_header(self):
pass

def get_body(self):
pass

 

2、search模糊查询

1.判断用户是否配置,配置才显示search框, get查询
search_fields = ['title', 'price']

显示key_words{{ showlist.config.key_words }}
{% if showlist.config.search_fields %}
<form action="" class="pull-right">
<input type="text" name="q" value="{{ showlist.config.key_words }}"><button>submit</button>
</form>
{% endif %}

2.Q对象
# 获取search得Q对象
search_connection = self.get_search_condition(request)

# print("connection:",search_connection)
# connection: (or: ('title__contains', '3'), ('price__contains', '3'))

# 筛选当前表得所有数据
data_list = self.model.objects.all().filter(search_connection)

3.Q查询
两种方式,一种可以放str,就是下面这种,一种放字段;

def get_search_condition(self, request):
key_words = request.GET.get('q', "")
self.key_words = key_words

# self.search_fields ['title','price']

from django.db.models import Q
search_connection = Q()
if key_words:
search_connection.connector = "or"
for search_field in self.search_fields:
search_connection.children.append((search_field+"__contains", key_words))

return search_connection

4.模糊查询
(title__contains)(price__contains)
search_connection.children.append((search_field+"__contains", key_words))

 

 

 

3、action批量初始化

知识点

1.用户可自定义配置
def patch_init(self, request, queryset):
# print("queryset",queryset)
queryset.update(price=123)

# return HttpResponse('批量初始化OK')

patch_init.short_description = "批量初始化"
actions = [patch_init]

2.无论有没有配置,都会有一个默认得批量删除
def patch_delete(self, request, queryset):
queryset.delete()
patch_delete.short_description = "批量删除"

def new_actions(self):
temp = []
temp.append(ModelStark.patch_delete)
temp.extend(self.actions)

return temp

3.展示页面 option
传过去得数据: __name__ (方法名传过去,做为value,为之后反射做准备)
self.actions = self.config.new_actions()

def get_action_list(self):
temp = []
for action in self.actions:
temp.append({
"name": action.__name__,
"desc":action.short_description
})

return temp

4.前端
主要就是将:方法名赋值给option得value, form post请求,将值传到后台
<select name="action" id="" style="width: 200px; padding: 5px 8px; display: inline-block; ">
<option value="">------------</option>
{% for item in showlist.get_action_list %}
<option value="{{ item.name }}">{{ item.desc }}</option>
{% endfor %}
</select>

5.后台
接收用户选中得数据,action selected_pk
反射:action_func = getattr(self, action)
过滤查询:queryset: queryset = self.model.objects.filter(pk__in=selected_pk)
执行反射回来得函数: action_func(request, queryset)

def list_view(self, request):
if request.method == "POST":
print("request.POST:",request.POST)
# 'action': ['patch_init'], 'selected_pk': ['1', '2']
action = request.POST.get('action')
selected_pk = request.POST.getlist('selected_pk')
action_func = getattr(self, action) # 反射
queryset = self.model.objects.filter(pk__in=selected_pk) # 秒!!!
ret = action_func(request, queryset)
# return ret

...

 

posted @ 2018-08-18 14:45  venicid  阅读(350)  评论(0编辑  收藏  举报