• Python Day 76 Django框架 CRM项目(版本二)


      ##更新内容

    #1、list_display_links
    
    #2、form与modelform
    
    #3、bulk_create批量插入数据
    
    #4、封装展示类:
    
    #5、使用分页器

    #6、自动保存搜索条件,即保存url地址状态

      ##list_display_links

    #1、实现给相应的字段添加a标签,连接功能,点击可以跳转、
            def list_view(self, request):
                #查看self.model  <class 'app01.models.Book'> 那张表查看就代表谁
                # print(self.model)
    
                queryset = self.model.objects.all()
                # 表头展示
                header_list = []
                for field_or_func in self.get_new_list():
                    if isinstance(field_or_func,str):
                        if field_or_func == '__str__': #当用户没有指定list_display 默认展示当前表的大写名字
                            val = self.model._meta.model_name.upper()
                        else:
                            val = self.model._meta.get_field(field_or_func).verbose_name
                    else:
                        val = field_or_func(self,is_header=True)
                    header_list.append(val)
                #表单展示
                body_list = [] #格式定义 [[obj1.title,obj1.price],[obj2.title,obj2.price],[]]
    
                for obj in queryset:
                    tmp = []
                    for field_or_func in self.get_new_list():#注意这里的list_display查找顺序,先查自己的,在查全局的,然后循环要展示的字段
                        if isinstance(field_or_func,str):
                            val = getattr(obj,field_or_func) #通过反射获取obj对象中field字段所对应的值
                            if field_or_func in self.list_display_links:
                                _url = self.get_reverse_url('edit',obj)
                                val = mark_safe('<a href="%s">%s</a>'%(_url,val))
                        else:
                            val = field_or_func(self,obj=obj)
                        tmp.append(val)
    
                    body_list.append(tmp)
    
    
                return render(request,'stark/list_view.html',locals())
    #2、当表中存在a标签链接后删除默认的编辑功能字段
            def get_new_list(self):
                tmp=[]
                tmp.append(ModelStark.check_box)
                tmp.extend(self.list_display)
                if not self.list_display_links:
                    tmp.append(ModelStark.edit_col)
                tmp.append(ModelStark.delete_col)
                return tmp
    View Code

      ##form与modelform

    模型表的增删改查
    
    form组件
        1.校验数据
        2.渲染标签
        3.展示信息
    
    modelform用法
        class StudentList(ModelForm):
            class Meta:
                model =Student #对应的Model中的类
                fields = "__all__" #字段,如果是__all__,就是表示列出所有的字段
                exclude = None #排除的字段
                #error_messages用法:
                error_messages = {
                'name':{'required':"用户名不能为空",},
                'age':{'required':"年龄不能为空",},
                }
                #widgets用法,比如把输入用户名的input框给为Textarea
                #首先得导入模块
                from django.forms import widgets as wid #因为重名,所以起个别名
                widgets = {
                "name":wid.Textarea(attrs={"class":"c1"}) #还可以自定义属性
                }
                #labels,自定义在前端显示的名字
                labels= {
                "name":"用户名"
                }

      ##modelform实现增删改查

    #1、modelform的前端渲染跟forms组件一模一样实现增删改查
        自定义配置类:C:starkproapp01stark.py
            class BookConfig(ModelStark):
    
                list_display = ['title','price','publishDate','publish']
                list_display_links = ['title','price']
    
                class BookModelForm(ModelForm):
                    class Meta:
                        model = models.Book
                        fields = '__all__'
                        from django.forms import widgets as wid
                        widgets = {
                            'title':wid.TextInput(attrs={'class':'form-control'}),
                            'price':wid.TextInput(attrs={'class':'form-control'}),
                            'publishDate':wid.DateInput(attrs={'class':'form-control'}),
                            'publish':wid.Select(attrs={'class':'form-control'}),
                            'authors':wid.SelectMultiple(attrs={'class':'form-control'})
                        }
                model_form_class = BookModelForm
        默认配置类:C:starkprostarkservicestark.py
            class ModelStark(object):
                #ModelStark中时默认的参数,用户自定义的的在C:starkproapp01stark.py
                list_display = ['__str__',]
                list_display_links = []
                model_form_class = None
                
                def list_view(self, request):
                    #给前端(展示列表list_view)传一个反向解析出来的url,作为跳转使用
                    url = self.get_reverse_url('add')
                 ##默认定义一个model_form_class,如果自定义配置类在C:starkproapp01stark.py 中配置了,就使用用户自定义的
                def get_model_form(self):
                    if self.model_form_class:
                        return self.model_form_class
                    from django.forms import ModelForm
                    class ModelFormClass(ModelForm):
                        class Meta:
                            model = self.model
                            fields = '__all__'
                    return ModelFormClass
                
                def add_view(self, request):
                    model_form_class = self.get_model_form()
                    model_form_obj = model_form_class()
                    if request.method == 'POST':
                        model_form_obj = self.model_form_class(request.POST)
                        if model_form_obj.is_valid():
                            model_form_obj.save()
                            return redirect(self.get_reverse_url('list'))
                    return render(request, 'stark/add_view.html', locals())
    
                def edit_view(self, request, id):
                    edit_obj = self.model.objects.filter(pk=id).first()
                    model_form_class = self.get_model_form()
                    model_form_obj =model_form_class(instance=edit_obj)
                    if request.method  == 'POST':
                        model_form_obj = model_form_class(request.POST,instance=edit_obj)
                        if model_form_obj.is_valid():
                            model_form_obj.save()
                            return redirect(self.get_reverse_url('list'))
                    return render(request,'stark/edit_view.html',locals())
    
                def delete_view(self, request, id):
                    self.model.objects.filter(pk=id).delete()
                    return redirect(self.get_reverse_url('list'))
                
    #2、在后端代码更加精简
        母版:base.html
            <!DOCTYPE html>
            <html lang="en">
            <head>
                <meta charset="UTF-8">
                <title>Title</title>
                <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
                <link rel="stylesheet" href="/static/bs-3.3.7/css/bootstrap.css">
                <script src="/static/bs-3.3.7/js/bootstrap.min.js"></script>
                <style>
                    input[name],select {
                        display: block;
                         100%;
                        height: 34px;
                        padding: 6px 12px;
                        font-size: 14px;
                        line-height: 1.42857143;
                        color: #555;
                        background-color: #fff;
                        background-image: none;
                        border: 1px solid #ccc;
                        border-radius: 4px;
                        -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
                        box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
                        -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
                        -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
                        transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
                    }
                </style>
            </head>
            <body>
            <div class="container">
                <div class="row">
                    {% block content %}
    
                    {% endblock %}
                </div>
            </div>
            </body>
            </html>
        子板:增加页面 add_view.html
            {% extends 'stark/base.html' %}
            {% block content %}
                <div class="col-md-6 col-md-offset-3">
                        <h2 class="text-center">添加数据</h2>
                        <form action="" method="post">
                            {% csrf_token %}
                            {% for form_obj in model_form_obj %}
                                <p>{{ form_obj.label }}{{ form_obj }}
                                    <span>{{ form_obj.error.0 }}</span>
                                </p>
    
                            {% endfor %}
                            <input type="submit" class="btn btn-success pull-right">
                        </form>
                    </div>
            {% endblock %}
        子板:编辑页面 edit_view.html
            {% extends 'stark/base.html' %}
            {% block content %}
                <div class="col-md-6 col-md-offset-3">
                        <h2 class="text-center">添加数据</h2>
                        <form action="" method="post">
                            {% csrf_token %}
                            {% for form_obj in model_form_obj %}
                                <p>{{ form_obj.label }}{{ form_obj }}
                                    <span>{{ form_obj.error.0 }}</span>
                                </p>
    
                            {% endfor %}
                            <input type="submit" class="btn btn-success pull-right">
                        </form>
                    </div>
            {% endblock %}
    View Code

      ##bulk_create批量插入数据

     # for i in range(1000):
     #     models.Publish.objects.create(name='%s出版社'%i)
    
     # obj_list = []
     # for i in range(10000):
     #     obj_list.append(models.Publish(name='出版社%s'%i))
     # models.Publish.objects.bulk_create(obj_list)

      ##自动保存搜索条件

    #1、核心代码:
        
        import copy
        params = copy.deepcopy(request.GET) #request字典是不能修改的,get请求后端获取到的数据格式如:use=owen&pwd=111  想要修改的话直通通过深拷贝方式
        params['xxx'] = 123 #然后可以进行修改
        print(params)
        print(params.urlencode())  # 将字典变成urlencoded数据格式,就能拿到数据格式为:use=owen&pwd=111
        return render(request,'publish.html',locals())
    
    
    #2、分页器使用:
            queryset = models.Publish.objects.all()
    
            page_obj = Pagination(request.GET.get('page',1),queryset.count(),request)#给分页器传入request
            page_queryset = queryset[page_obj.start:page_obj.end]

      ##封装展示类

    #1、展示类
    class ShowList:#注意self的区别
        def __init__(self,config_obj,queryset):
            self.config_obj = config_obj #对应每一个配置类对象
            self.queryset = queryset
    
        def get_header(self):
            # 表头展示
            header_list = []
            for field_or_func in self.config_obj.get_new_list():
                if isinstance(field_or_func, str):
                    if field_or_func == '__str__':  # 当用户没有指定list_display 默认展示当前表的大写名字
                        val = self.config_obj.model._meta.model_name.upper()
                    else:
                        val = self.config_obj.model._meta.get_field(field_or_func).verbose_name
                else:
                    val = field_or_func(self, is_header=True)
                header_list.append(val)
            return header_list
        def get_body(self):
            # 表单展示
            body_list = []  # 格式定义 [[obj1.title,obj1.price],[obj2.title,obj2.price],[]]
    
            for obj in self.queryset:
                tmp = []
                for field_or_func in self.config_obj.get_new_list():  # 注意这里的list_display查找顺序,先查自己的,在查全局的,然后循环要展示的字段
                    if isinstance(field_or_func, str):
                        val = getattr(obj, field_or_func)  # 通过反射获取obj对象中field字段所对应的值
                        if field_or_func in self.config_obj.list_display_links:
                            _url = self.config_obj.get_reverse_url('edit', obj)
                            val = mark_safe('<a href="%s">%s</a>' % (_url, val))
                    else:
                        val = field_or_func(self.config_obj, obj=obj)
                    tmp.append(val)
    
                body_list.append(tmp)
            return body_list
    #2、默认配置类
    class ModelStark(object):
            def list_view(self, request):
            #查看self.model  <class 'app01.models.Book'> 那张表查看就代表谁
            # print(self.model)
    
            queryset = self.model.objects.all()
            show_obj = ShowList(self,queryset)#传self :为展示类对象
    
    
            url = self.get_reverse_url('add')
            return render(request,'stark/list_view.html',locals())
    #3、前端                 </tbody>
    
        {% extends 'stark/base.html' %}
        {% block content %}
            <h2 class="text-center">数据展示</h2>
                <div class="col-md-8 col-md-offset-2">
                    <a href="{{ url }}" class="btn btn-primary">添加数据</a>
                    <table class="table table-striped table-bordered table-hover">
                        <thead>
                        <tr>
                            {% for foo in show_obj.get_header %}
                                <td>{{ foo }}</td>
                            {% endfor %}
                        </tr>
                        </thead>
                        <tbody>
                        {% for body in show_obj.get_body %}
                            <tr>
                                {% for  foo in body %}
                                    <td>
                                        {{ foo }}
                                    </td>
                                {% endfor %}
                            </tr>
                        {% endfor %}
                        </tbody>
    
                    </table>
                </div>
        {% endblock %}
    View Code

      ##使用分页器

    class Pagination(object):
    def __init__(self, current_page, all_count,request, per_page_num=10, pager_count=11):#添加request参数
        """
        封装分页相关数据
        :param current_page: 当前页
        :param all_count:    数据库中的数据总条数
        :param per_page_num: 每页显示的数据条数
        :param pager_count:  最多显示的页码个数
    
        用法:
        queryset = model.objects.all()
        page_obj = Pagination(current_page,all_count)
        page_data = queryset[page_obj.start:page_obj.end]
        获取数据用page_data而不再使用原始的queryset
        获取前端分页样式用page_obj.page_html
        """
        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
    
        # 总页码
        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
        self.params = copy.deepcopy(request.GET) #对传入的request参数进行 深拷贝
    
    @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/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_end = self.all_pager + 1
                    pager_start = self.all_pager - self.pager_count + 1
                else:
                    pager_start = self.current_page - self.pager_count_half
                    pager_end = self.current_page + self.pager_count_half + 1
    
        page_html_list = []
        # 添加前面的nav和ul标签
        page_html_list.append('''
                    <nav aria-label='Page navigation>'
                    <ul class='pagination'>
                ''')
        first_page = '<li><a href="?page=%s">首页</a></li>' % (1)
        page_html_list.append(first_page)
    
        if self.current_page <= 1:
            prev_page = '<li class="disabled"><a href="#">上一页</a></li>'
        else:
            prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1,)
    
        page_html_list.append(prev_page)
    
        for i in range(pager_start, pager_end):
            self.params['page'] = i  #实现动态变化页码
            if i == self.current_page:
                temp = '<li class="active"><a href="?%s">%s</a></li>' % (self.params.urlencode(), i,)
            else:
                temp = '<li><a href="?%s">%s</a></li>' % (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:
            next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1,)
        page_html_list.append(next_page)
    
        last_page = '<li><a href="?page=%s">尾页</a></li>' % (self.all_pager,)
        page_html_list.append(last_page)
        # 尾部添加标签
        page_html_list.append('''
                                           </nav>
                                           </ul>
                                       ''')
        return ''.join(page_html_list)
    my_page分页器代码
    #1、展示类
    class ShowList:
        def __init__(self,config_obj,queryset,request):
            self.config_obj = config_obj
            self.queryset = queryset
            self.request = request
            current_page = self.request.GET.get('page',1)
            self.page_obj = Pagination(current_page=current_page,all_count=self.queryset.count(),request=self.request)
            self.page_queryset = self.queryset[self.page_obj.start:self.page_obj.end]
        def get_body(self):
            # 表单展示
            body_list = []  # 格式定义 [[obj1.title,obj1.price],[obj2.title,obj2.price],[]]
    
            for obj in self.page_queryset:#使用分页器
                tmp = []
                for field_or_func in self.config_obj.get_new_list():  # 注意这里的list_display查找顺序,先查自己的,在查全局的,然后循环要展示的字段
                    if isinstance(field_or_func, str):
                        val = getattr(obj, field_or_func)  # 通过反射获取obj对象中field字段所对应的值
                        if field_or_func in self.config_obj.list_display_links:
                            _url = self.config_obj.get_reverse_url('edit', obj)
                            val = mark_safe('<a href="%s">%s</a>' % (_url, val))
                    else:
                        val = field_or_func(self.config_obj, obj=obj)
                    tmp.append(val)
    
                body_list.append(tmp)
            return body_list        
    
    #2、默认配置类
    class ModelStark(object):
            def list_view(self, request):
            #查看self.model  <class 'app01.models.Book'> 那张表查看就代表谁
            # print(self.model)
    
            queryset = self.model.objects.all()
            show_obj = ShowList(self,queryset,request)#创建展示类对象,给展示类传递一个request
    
    
            url = self.get_reverse_url('add')
            return render(request,'stark/list_view.html',locals())
    
    #3、前端
        {{ show_obj.page_obj.page_html|safe }}
    分页器使用代码
  • 相关阅读:
    生成不带签名(BOM)的UTF8格式的XML
    矢量数据的裁剪及合并
    使用dotNET_Reactor4.7加密后的dll在VS2010中无法打包
    加密后的程序在Win8中无法运行
    修改jpg的图片大小
    shapefile中dbf的数据格式(转载)
    shapefile 输出的地理处理注意事项(转载)
    linxu下面的绝对路径和相对路径
    go中的类型转换成interface之后如何复原
    使用docker部署一个go应用
  • 原文地址:https://www.cnblogs.com/liangzhenghong/p/11303574.html
Copyright © 2020-2023  润新知