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

 

转载于:https://www.cnblogs.com/ShenJunHui6/p/10858996.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值