zoukankan      html  css  js  c++  java
  • CRM总结

    admin参数配置

    list_display:

    指定数据展示的字段

    注意多对多字段不能放在list_display列表里进行展示

    list_display_links

    指定跳转字段(跳转到当前字段所在数据的编辑页)

    search_fields

    搜索title里面1或者price包含1的数据

    1.在页面上渲染出搜索框

    2.支持条件与条件之间的"或"查询

    list_filter

    1.它不是用来筛选普通字段的,它是用来帮你筛选外键字段的

    2.支持组合查询

    actions

    批量处理数据

    # 先定义一个批量处理函数
    def patch_init(self,request,queryset):
            queryset.update(price=666)
    # 给这个函数命名  不写就是首字母大写的函数名
    patch_init.short_description = '价格批量初始化'
    # 配置到配置类中
    actions = [patch_init]

    Django启动会加载配置文件

    from django.utils.module_loading import autodiscover_modules
    def autodiscover():
                autodiscover_modules('admin', register_to=site)
    #django启动的时候就会自动执行每一个应用下的admin.py文件

    admin site源码

    class AdminSite(object):
            def __init__(self, name='admin'):
                    self._registry = {}  # model_class class -> admin_class instance
            
            def register(self, model, admin_class=None, **options):
                    if not admin_class:
                            admin_class = ModelAdmin  # 所有模型表公共的配置
    
                # (******)  {'模型表变量名':'模型表配置类对象'}
                    self._registry[model] = admin_class(model)  
                
    site = AdminSite()
    self._registry 一定一定要搞清楚的是字典里面的键值对到底是什么!!!
            <class 'django.contrib.auth.models.Group'> auth.GroupAdmin
            <class 'django.contrib.auth.models.User'> auth.UserAdmin
            <class 'app01.models.Book'> app01.BookConfig
            <class 'app01.models.Author'> app01.ModelAdmin
            <class 'app01.models.Publish'> app01.ModelAdmin
            <class 'app01.models.AuthorDetail'> app01.ModelAdmin
            
            
            <class 'django.contrib.auth.models.Group'> auth.GroupAdmin
            <class 'django.contrib.auth.models.User'> auth.UserAdmin
            <class 'app01.models.Book'> app01.BookConfig
            <class 'app01.models.Author'> app01.ModelAdmin

    路由分发的本质

    url(r'^test/',([],None,None))

    一级分发

    url(r'^test/',([    url(r'^test_1/',test_1),    url(r'^test_2/',test_2)],None,None))

    二级分发

    url(r'^test/', ([
                url(r'^test_1/', ([
                      url(r'^test_1_1/', test_1_1),
                      url(r'^test_1_2/', test_1_2),
                      url(r'^test_1_3/', test_1_3),
                                  ], None, None)),
                url(r'^test_2/', test_2)
                        ], None, None))

    url设计

    http://127.0.0.1:8000/admin/app01/book/  书籍的查看
    http://127.0.0.1:8000/admin/app01/book/1/change/  书籍的编辑
    http://127.0.0.1:8000/admin/app01/book/1/delete/  书籍的删除
    http://127.0.0.1:8000/admin/app01/book/add/  书籍的添加
    #获取模型表所在应用名 model_class就是你自定义的模型表变量名
    app_label = model_class._meta.app_label
    #获取模型表的字符串小写名
    model_name = model_class._meta.model_name

    python console中测试

    from app01 import models
    models.Book._meta.model_name  #'book'
    moeels.Book._meta.app_label  #'app01'

    一个项目可以有多个应用,一个应用可以被多个项目使用!

    stark组件启动

    1.settings配置文件中注册app的时候,会加载应用下的apps.py的类

    from django.utils.module_loading import autodiscover_modules
    class StarkConfig(AppConfig):
            name = 'stark'
                
            def ready(self):
                    autodiscover_modules('stark')
    # 固定写法,即可实现项目已启动自动访问每一个应用下的stark.py文件 

    stark组件注册

    from app01 import models
    models.Book._meta.get_field('title')#获取模型表中的某个字段对象
    #<django.db.models.fields.CharField: title>
    #获取模型表中的某个字段对象的属性
    models.Book._meta.get_field('title').verbose_name
    #'名称'
    models.Book._meta.get_field('price').verbose_name
    #'price'

    反向解析

    别名格式:'应用名/模型表名/功能名'

    def get_urls(self):
            tmp = [
                url(r'^$', self.list_view, name='%s_%s_list' % (self.app_label, self.model_name)),
                url(r'^add/', self.add_view, name='%s_%s_add' % (self.app_label, self.model_name)),
                url(r'^edit/(d+)/', self.edit_view, name='%s_%s_edit' % (self.app_label, self.model_name)),
                url(r'^delete/(d+)/', self.delete_view, name='%s_%s_delete' % (self.app_label, self.model_name)),
            ]
            return tmp

    由于所对应的表不同前端渲染页面时需要区分不同的展示效果即每个路由不同

    这里的self指的是每次访问的数据表的不同使这个self动态变化

    封装了一个反向解析的通用方法

    def get_reverse_url(self, type, object=None):
        if object:
            _url = reverse('%s_%s_%s' % (self.app_label, self.model_name, type), args=(object.pk,))
        else:
            _url = reverse('%s_%s_%s' % (self.app_label, self.model_name, type))
        return _url

    判断这个object参数是否有值来返回不同的结果

    form与modelform

    def get_model_form_class(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__'
                widgets = self.get_class()
    
        return ModelFormClass
    def get_class(self):
            for i in self.model._meta.fields:
                if i.__class__.__name__ == 'DateField':
                    a = getattr(i, "__str__")().split('.')[-1]
                    from django.forms import widgets as wid
                    widgets = {
                        a: wid.DateInput(attrs={'class': 'form-control', 'type': 'date'}),
                    }
                    return widgets

    多写了一个当你的模型表中某个字段名是日期类型,让它前端渲染页面的时候使input框中的type是date

    注册了的模型表的增删改查

    需要注意的是使用modelform进行数据新增个修改操作的时候,用的都是save()方法

    通过instance参数来区分是修改还是新增操作

    分页器>>>保存搜索条件

    class Pagination(object):
        def __init__(self, current_page, all_count, params, per_page_num=2, pager_count=5):
            """
            封装分页相关数据
            :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(params)
    
        @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)
    #多传入了一个params参数进去用到copy的深度拷贝(deepcopy)
    保存搜索条件分页器

    stark组件核心代码

    from django.conf.urls import url
    from django.shortcuts import HttpResponse, reverse, render, redirect
    from django.utils.safestring import mark_safe
    from app01.utils.mypag import Pagination
    from django.db.models import Q
    
    
    # 定一个展示类
    class ShowList(object):
        def __init__(self, config_object, queryset, request):
            self.config_object = config_object
            self.queryset = queryset
            self.request = request
            current_page = self.request.GET.get('page', 1)
            self.page_object = Pagination(current_page=current_page, all_count=self.queryset.count(),
                                          params=self.request.GET)
            self.page_queryset = self.queryset[self.page_object.start:self.page_object.end]
    
        # 获取头部展示
        def get_header(self):
            header_list = []
            for header in self.config_object.get_new_list_display():
                if isinstance(header, str):
                    if header == '__str__':
                        value = self.config_object.model._meta.model_name.upper()
                    else:
                        value = self.config_object.model._meta.get_field(header).verbose_name
                else:
                    value = header(self.config_object, is_header=True)
                header_list.append(value)
            return header_list
    
        # 获取身体展示
        def get_body(self):
            body_list = []
            for data in self.page_queryset:
                tmp = []
                for field_or_func in self.config_object.get_new_list_display():
                    if isinstance(field_or_func, str):
                        value = getattr(data, field_or_func)
                        if field_or_func in self.config_object.list_display_links:
                            _url = self.config_object.get_reverse_url('edit', data)
                            value = mark_safe('<a href ="%s">%s</a>' % (_url, value))
                    else:
                        value = field_or_func(self.config_object, object=data)
                    tmp.append(value)
                body_list.append(tmp)
            return body_list
    
        # 获取action
        def get_action(self):
            tmp = []
            for action in self.config_object.actions:
                tmp.append({
                    'name': action.__name__,
                    'desc': action.desc
                })
            return tmp
    
        # 获取filter
        def get_filter(self):
            tmp_dict = {}
            # 循环拿到list_filter里面的外键字段字符串
            for filter_field in self.config_object.list_filter:
                tmp = []
                # 获取关键字所对应的关联表
                rel_model = self.config_object.model._meta.get_field(filter_field).rel.to
                # 获取所有所有关联表的数据
                rel_queryset = rel_model.objects.all()
                filter_value = self.request.GET.get(filter_field)
                import copy
                params = copy.deepcopy(self.request.GET)
                if filter_field in params:
                    params.pop(filter_field)
                    value = "<a href='?%s'>All</a>" % params.urlencode()
                else:
                    value = "<a href='?'>All</a>"
                tmp.append(mark_safe(value))
                params = copy.deepcopy(self.request.GET)
                for data in rel_queryset:
                    params[filter_field] = data.pk
                    if filter_value == str(data.pk):
                        value = "<a href='?%s' class='active'>%s</a>" % (params.urlencode(), str(data))
                    else:
                        value = "<a href='?%s'>%s</a>" % (params.urlencode(), str(data))
                    tmp.append(mark_safe(value))
                tmp_dict[filter_field] = tmp
            return tmp_dict
    
    
    class ModelStark(object):
        list_display = ['__str__', ]
        list_display_links = []
        model_form_class = None
        search_fields = []
        actions = []
        list_filter = []
    
        # 获取如果是date字段类型默认使type变为date
        def get_date_class(self):
            for i in self.model._meta.fields:
                if i.__class__.__name__ == 'DateField':
                    date_class = getattr(i, "__str__")().split('.')[-1]
                    from django.forms import widgets as wid
                    widgets = {
                        date_class: wid.DateInput(attrs={'class': 'form-control', 'type': 'date'}),
                    }
                    return widgets
    
        # 设置默认input框
        def get_model_form_class(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__'
                    widgets = self.get_date_class()
    
            return ModelFormClass
    
        def __init__(self, model):
            self.model = model
            self.app_label = self.model._meta.app_label
            self.model_name = self.model._meta.model_name
    
        # 反向解析
        def get_reverse_url(self, type, object=None):
            if object:
                _url = reverse('%s_%s_%s' % (self.app_label, self.model_name, type), args=(object.pk,))
            else:
                _url = reverse('%s_%s_%s' % (self.app_label, self.model_name, type))
            return _url
    
        # 主页展示编辑栏
        def edit_col(self, is_header=False, object=None):
            if is_header:
                return '编辑'
            _url = self.get_reverse_url('edit', object)
            return mark_safe('<a href ="%s">编辑</a>' % _url)
    
        # 主页展示删除栏
        def delete_col(self, is_header=False, object=None):
            if is_header:
                return '删除'
            _url = self.get_reverse_url('delete', object)
            return mark_safe('<a href ="%s">删除</a>' % _url)
    
        # 主页展示checkbox栏
        def check_col(self, is_header=False, object=None):
            if is_header:
                return '选择'
            return mark_safe('<input type="checkbox" name="select_action" value="%s">' % object.pk)
    
        # 获取新的list_display
        def get_new_list_display(self):
            tmp = []
            tmp.append(ModelStark.check_col)
            tmp.extend(self.list_display)
            if not self.list_display_links:
                tmp.append(ModelStark.edit_col)
            tmp.append(ModelStark.delete_col)
            return tmp
    
        # 获取搜索
        def get_search(self, request, queryset):
            self.key_word = ''
            key_word = request.GET.get('search')
            if key_word:
                self.key_word = key_word
                q = Q()
                q.connector = 'or'
                for search_field in self.search_fields:
                    q.children.append(('%s__icontains' % search_field, key_word))
                queryset = queryset.filter(q)
            return queryset
    
        # 获取过滤
        def get_filter(self, request, queryset):
            q = Q()
            for filter_field in self.list_filter:
                value = request.GET.get(filter_field)
                if value:
                    q.children.append((filter_field, value))
                queryset = queryset.filter(q)
            return queryset
    
        # 展示所有的信息
        def list_view(self, request):
            # action操作
            if request.method == 'POST':
                #   交给用户自定义函数的字符串名
                action_name = request.POST.get('action')
                if action_name:
                    # 获取用户想要批量处理的数据主键值
                    pk_list = request.POST.getlist('select_action')
                    #         查出上述id值对应的queryset数据
                    action_queryset = self.model.objects.filter(pk__in=pk_list)
                    real_action = getattr(self, action_name)
                    real_action(request, action_queryset)
            # 获取对应模型表的所有数据
            queryset = self.model.objects.all()
            # search功能
            queryset = self.get_search(request, queryset)
            # filter功能
            queryset = self.get_filter(request, queryset)
            show_object = ShowList(self, queryset, request)
            url = self.get_reverse_url('add')
            return render(request, 'stark/list_view.html', locals())
    
        # 添加页面
        def add_view(self, request):
            # 获取modelform类变量名
            model_form_class = self.get_model_form_class()
            # 实例化modelform对象
            model_form_object = model_form_class()
            if request.method == "POST":
                # 获取加号对应的标签id
                pop_back_id = request.GET.get('pop_back_id')
                model_form_object = model_form_class(request.POST)
                if model_form_object.is_valid():
                    # 保存返回结果为当前保存对象
                    obj = model_form_object.save()
                    # 判断当前添加页面是否是加号触发
                    if pop_back_id:
                        pk = obj.pk
                        text = str(obj)
                        return render(request, 'stark/pop.html', locals())
                    return redirect(self.get_reverse_url('list'))
            from django.forms.models import ModelChoiceField
            for field_object in model_form_object:
                if isinstance(field_object.field, ModelChoiceField):
                    field_object.is_pop = True
                    real_model = self.model._meta.get_field(field_object.name).rel.to
                    real_app_label = real_model._meta.app_label
                    real_model_name = real_model._meta.model_name
                    url = reverse('%s_%s_add' % (real_app_label, real_model_name))
                    url = url + '?pop_back_id=%s' % field_object.auto_id
                    field_object.url = url
            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_class()
            model_form_object = model_form_class(instance=edit_obj)
            if request.method == 'POST':
                pop_back_id = request.GET.get('pop_back_id')
                model_form_object = model_form_class(request.POST, instance=edit_obj)
                if model_form_object.is_valid():
                    obj = model_form_object.save()
                    # 判断当前添加页面是否是加号触发
                    if pop_back_id:
                        pk = obj.pk
                        text = str(obj)
                        return render(request, 'stark/pop.html', locals())
                    model_form_object.save()
                    return redirect(self.get_reverse_url('list'))
            from django.forms.models import ModelChoiceField
            for field_object in model_form_object:
                if isinstance(field_object.field, ModelChoiceField):
                    field_object.is_pop = True
                    real_model = self.model._meta.get_field(field_object.name).rel.to
                    real_app_label = real_model._meta.app_label
                    real_model_name = real_model._meta.model_name
                    url = reverse('%s_%s_add' % (real_app_label, real_model_name))
                    url = url + '?pop_back_id=%s' % field_object.auto_id
                    field_object.url = url
            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'))
    
        # 获取路由
        def get_urls(self):
            tmp = [
                url(r'^$', self.list_view, name='%s_%s_list' % (self.app_label, self.model_name)),
                url(r'^add/', self.add_view, name='%s_%s_add' % (self.app_label, self.model_name)),
                url(r'^edit/(d+)/', self.edit_view, name='%s_%s_edit' % (self.app_label, self.model_name)),
                url(r'^delete/(d+)/', self.delete_view, name='%s_%s_delete' % (self.app_label, self.model_name)),
            ]
            return tmp
    
    
    class StarkSite():
        def __init__(self, name='admin'):
            self._registry = {}
    
        def register(self, model, admin_class=None, **options):
            if not admin_class:
                admin_class = ModelStark
            self._registry[model] = admin_class(model)
    
        def get_urls(self):
            tmp = []
            for model_class, config_obj in self._registry.items():
                app_label = model_class._meta.app_label
                model_name = model_class._meta.model_name
                tmp.append(
                    url(r'^%s/%s/' % (app_label, model_name), (config_obj.get_urls(), None, None))
                )
            return tmp
    
        @property
        def urls(self):
            return self.get_urls(), None, None
    
    
    # 单利模式
    site = StarkSite()
    stark.py

    html代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
        <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
        <script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script>
        <style>
            table {
                margin-top: 10px;
            }
    
            .active {
                color: red;
            }
    
            .plus-father {
                position: relative;
            }
    
            .plus {
                color: #369;
                font-size: 24px;
                position: absolute;
                top: 19px;
                right: -28px;
            }
        </style>
        {% block css %}
    
        {% endblock %}
    </head>
    <body>
    <div class="container">
        <div class="row">
            {% block content %}
    
            {% endblock %}
        </div>
    </div>
    </body>
    </html>
    base.html
    {% extends 'stark/base.html' %}
    {% block css %}
        <link rel="stylesheet" href="/static/common.css">
    {% endblock %}
    {% block content %}
        <h3 class="text-center">添加数据</h3>
        <form action="" method="post">
            {% csrf_token %}
            {% for foo in model_form_object %}
                <div class="plus-father">
                    <p>{{ foo.label }}{{ foo }}</p>
                    {% if foo.is_pop %}
                        <span class="plus" onclick="WindowOpen('{{ foo.url }}')">+</span>
                    {% endif %}
                </div>
            {% endfor %}
            <input type="submit" class="btn pull-right btn-primary">
        </form>
        <script>
            function WindowOpen(url) {
                window.open(url, '', 'width=800px,height=400px')
            }
    
            function addOption(pop_back_id, pk, text) {
                let opt = document.createElement('option');
                opt.value = pk;
                opt.innerHTML = text;
                opt.selected = 'selected';
                let sel = document.getElementById(pop_back_id);
                sel.appendChild(opt);
            }
        </script>
    {% endblock %}
    add_view.html
    {% extends 'stark/base.html' %}
    {% block css %}
        <link rel="stylesheet" href="/static/common.css">
    {% endblock %}
    {% block content %}
        <h3 class="text-center">编辑数据</h3>
        <form action="" method="post">
            {% csrf_token %}
            {% for foo in model_form_object %}
                <div class="plus-father">
                    <p>{{ foo.label }}{{ foo }}</p>
                    {% if foo.is_pop %}
                        <span class="plus" onclick="WindowOpen('{{ foo.url }}')">+</span>
                    {% endif %}
                </div>
            {% endfor %}
            <input type="submit" class="btn pull-right btn-danger">
        </form>
        <script>
            function WindowOpen(url) {
                window.open(url, '', 'width=800px,height=400px')
            }
    
            function addOption(pop_back_id, pk, text) {
                let opt = document.createElement('option');
                opt.value = pk;
                opt.innerHTML = text;
                opt.selected = 'selected';
                let sel = document.getElementById(pop_back_id);
                sel.appendChild(opt);
            }
        </script>
    {% endblock %}
    edit_view.html
    {% extends 'stark/base.html' %}
    {% block content %}
        <div class="col-md-9">
            <h3 class="text-center" style="margin-bottom: 30px">数据展示</h3>
            <a href="{{ url }}" class="btn btn-primary pull-right" style="margin-bottom: 10px">添加数据</a>
            {#    search功能开始#}
            {% if show_object.config_object.search_fields %}
                <form class="form-inline">
                    <div class="form-group">
                        <div class="input-group">
                            <input type="text" class="form-control" id="exampleInputAmount" placeholder="关键字" name="search"
                                   value="{{ show_object.config_object.key_word }}">
                        </div>
                    </div>
                    <button type="submit" class="btn btn-success">Search</button>
                </form>
            {% endif %}
            {#    search功能结束#}
            {#    action功能开始#}
            <form action="" class="form-inline" method="post" style="margin-top: 10px">
                {% csrf_token %}
                <select name="action" class="form-control">
                    <option value="">----------------</option>
                    {% for foo in show_object.get_action %}
                        <option value="{{ foo.name }}">{{ foo.desc }}</option>
                    {% endfor %}
                </select>
                <input type="submit" class="btn btn-danger" value="GO">
                {#        action功能结束#}
                {#    表头表单功能开始#}
                <table class="table-striped table table-bordered table-hover">
                    <thead class="text-center">
                    <tr>
                        {% for head in show_object.get_header %}
                            <th>{{ head }}</th>
                        {% endfor %}
    
                    </tr>
                    </thead>
                    <tbody class="text-center">
                    {% for body in show_object.get_body %}
                        <tr>
                            {% for foo in body %}
                                <td>{{ foo }}</td>
                            {% endfor %}
                        </tr>
                    {% endfor %}
    
                    </tbody>
                </table>
                {#    表头表单功能结束#}
            </form>
            <div class="text-center">
                {{ show_object.page_object.page_html|safe }}
            </div>
        </div>
        <div class="col-md-3">
            {% if show_object.config_object.list_filter %}
                <div style="margin-top: 160px">
                    <div class="alert-info text-center">FILTER</div>
                    {% for k,v in show_object.get_filter.items %}
                        <div class="panel panel-default">
                            <div class="panel-heading">By {{ k }}</div>
                            <div class="panel-body">
                                {% for foo in v %}
                                    <p>{{ foo }}</p>
                                {% endfor %}
                            </div>
                        </div>
                    {% endfor %}
                </div>
            {% endif %}
        </div>
    {% endblock %}
    list_view
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
        <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
        <script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script>
    </head>
    <body>
    <script>
        window.opener.addOption('{{ pop_back_id }}', '{{ pk }}', '{{ text }}')
        window.close()
    </script>
    </body>
    </html>
    pop.html
    input[name], select {
        display: block;
        width: 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;
    }
    common.css
  • 相关阅读:
    css3新特性总结
    ES6常用特性总览
    前端第一次面试
    将一个行数在主线程执行的4中方法
    判断邮箱格式和图片压缩
    上传图片的实现
    导航右侧添加按钮、隐藏导航条和状态栏
    从相册选取图片展示并实现自定义事件
    cell添加选中时的背景图片、显示图片和图片自适应框的大小
    设置键盘无色和状态栏风火轮、屏幕截图
  • 原文地址:https://www.cnblogs.com/ShenJunHui6/p/10858996.html
Copyright © 2011-2022 走看看