手写一个admin 组件------STARK

开一个新的项目,,建立一个stark 包, 在里面创建一个service包,在service 包里创建一个stark.py 文件,

配置好环境, makemigreations, migreate.

settings.py 配置:

STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR,'static'),
]


INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config',
'stark.apps.StarkConfig',
]
from django.contrib import admin

配置好后:

app01下的modles.py
from django.db import models

# Create your models here.
from django.db import models

# Create your models here.
class Author(models.Model):
    nid = models.AutoField(primary_key=True)
    name=models.CharField( max_length=32)
    age=models.IntegerField()

    # 与AuthorDetail建立一对一的关系
    authorDetail=models.OneToOneField(to="AuthorDetail",on_delete=models.CASCADE)
    def __str__(self):
        return self.name

class AuthorDetail(models.Model):

    nid = models.AutoField(primary_key=True)
    birthday=models.DateField()
    telephone=models.BigIntegerField()
    addr=models.CharField( max_length=64)
    def __str__(self):
        return str(self.telephone)

class Publish(models.Model):
    nid = models.AutoField(primary_key=True)
    name=models.CharField( max_length=32)
    city=models.CharField( max_length=32)
    email=models.EmailField()

    def __str__(self):
        return self.name


class Book(models.Model):

    nid = models.AutoField(primary_key=True,verbose_name="ID")
    title = models.CharField( max_length=32,verbose_name="名称")
    publishDate=models.DateField()
    price=models.DecimalField(max_digits=5,decimal_places=2,verbose_name="价格")

    # 与Publish建立一对多的关系,外键字段建立在多的一方
    publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE,verbose_name="出版社")
    # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表
    authors=models.ManyToManyField(to='Author',)
    def __str__(self):
        return self.title
modles.py

app01创建一个的stark.py

# 完成注册功能
from app01 import models

from stark.service.stark import site,ModelStark

from django.utils.safestring import mark_safe

from django import forms
class BookModelForm(forms.ModelForm):
    class Meta:
        model=models.Book
        fields="__all__"
        error_messages={
            "title":{"required":" 该字段不能为空"}
        }


class BookConfig(ModelStark):


    def authors_display(self,obj=None,is_header=False):

        if is_header:
            return "作者"

        author_list=obj.authors.all()
        name_list=[author.name for author in author_list]
        return ','.join(name_list)


    list_display = ["title","price","publish",authors_display,]

    list_display_links=["title","price"]

    model_form_class=BookModelForm

    search_fields = ["title","price",]


    def patch_delete(self,request,queryset):
        queryset.delete()

    patch_delete.desc="批量删除"


    def patch_init(self,request,queryset):
        queryset.update(price=0)

    patch_init.desc="批量初始化"



    actions=[patch_delete,patch_init]


    list_filter=["publish","authors"]


site.register(models.Book,BookConfig)


site.register(models.Publish)
site.register(models.Author)
site.register(models.AuthorDetail)
stark.py

day81项目文件夹下的url.py文件

from django.conf.urls import url
from django.contrib import admin

from app01 import views

from stark.service.stark import site
urlpatterns = [
    url(r'^admin/', admin.site.urls),
url.py

stark包下的service包里的stark.py

from django.conf.urls import url

from django.shortcuts import HttpResponse,redirect,render

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

from stark.utils.page import Pagination
from django.db.models import Q

class Showlist(object):
    def __init__(self,conf_obj,queryset,request):
        self.conf_obj=conf_obj
        self.queryset=queryset
        self.request=request

        # 分页
        current_page=self.request.GET.get("page")
        pagination=Pagination(current_page,self.queryset.count(),self.request.GET,per_page_num=2)
        self.pagination=pagination

        self.page_queryset=self.queryset[self.pagination.start:self.pagination.end]

    def get_header(self):
        # 处理表头

        # header_list=["名称","价格","出版社"]
        header_list = []

        for field_or_func in self.conf_obj.get_new_list_display():  # ["title","price","publish",delete_col]

            if isinstance(field_or_func, str):

                if field_or_func == "__str__":
                    val = self.conf_obj.model._meta.model_name.upper()
                else:

                    field_obj = self.conf_obj.model._meta.get_field(field_or_func)
                    val = field_obj.verbose_name
            else:
                val = field_or_func(self.conf_obj, is_header=True)

            header_list.append(val)
        return header_list
    def get_body(self):
        #  处理表单数据
        data_list = []
        for obj in self.page_queryset:  # [obj1,obj2,obj3]
            temp = []

            for field_or_func in self.conf_obj.get_new_list_display():  # list_display = ["title","price","publish",delete_col]

                if isinstance(field_or_func, str):
                    val = getattr(obj, field_or_func)
                    if field_or_func in self.conf_obj.list_display_links:
                        val = mark_safe("<a href='%s'>%s</a>" % (self.conf_obj.get_reverse_url("change", obj), val))
                else:
                    val = field_or_func(self.conf_obj, obj)

                temp.append(val)
            data_list.append(temp)

        print(data_list)
        return data_list
    def get_actions(self):
        temp=[]
        for func in self.conf_obj.actions:# [patch_delete,]
            temp.append({
                "name":func.__name__,
                "desc":func.desc
            })

        return temp  #  [{"name":"patch_delete","desc":"批量删除"},]
    def get_filter_links(self):

        print("self.conf_obj.list_filter",self.conf_obj.list_filter) #  ['publish', 'authors']

        links_dict={}



        for filter_field in self.conf_obj.list_filter: # ['publish', 'authors']
            filter_field_obj=self.conf_obj.model._meta.get_field(filter_field)
            print(filter_field_obj)
            print(type(filter_field_obj))

            from django.db.models.fields.related import ForeignKey
            print("rel",filter_field_obj.rel.to)
            queryset=filter_field_obj.rel.to.objects.all()
            print("queryset",queryset)
            temp=[]

            import copy

            params=copy.deepcopy(self.request.GET)

            # 渲染标签

            current_filter_field_id=self.request.GET.get(filter_field)

            #  all 的链接标签
            params2 = copy.deepcopy(self.request.GET)
            if filter_field in params2:
                params2.pop(filter_field)
                all_link="<a href='?%s'>All</a>"%params2.urlencode()
            else:
                all_link = "<a href=''>All</a>"
            temp.append(all_link)

            for obj in queryset:
                params[filter_field]=obj.pk
                _url=params.urlencode()

                if current_filter_field_id==str(obj.pk):
                    s = "<a class='item active' href='?%s'>%s</a>" % (_url, str(obj))
                else:
                    s="<a class='item' href='?%s'>%s</a>"%(_url,str(obj))
                temp.append(s)

            links_dict[filter_field]=temp


        return  links_dict

class ModelStark(): # 默认配置类对象


    def __init__(self,model):
        self.model=model
        self.model_name = self.model._meta.model_name
        self.app_label = self.model._meta.app_label
        self.app_model_name=(self.app_label,self.model_name)
        self.key_word=""
    list_display=["__str__"]
    list_display_links=[]
    model_form_class=[]
    actions=[]

    search_fields=[]
    list_filter=[]


    # 反向解析出增删改查的url


    # # 删除url
    # def get_delete_url(self,obj):
    #     url_name = "%s_%s_delete" % self.app_model_name
    #     _url = reverse(url_name, args=(obj.pk,))
    #
    #     return _url
    #
    # # 编辑url
    # def get_change_url(self, obj):
    #     url_name = "%s_%s_change" % self.app_model_name
    #     _url = reverse(url_name, args=(obj.pk,))
    #
    #     return _url
    #
    #
    # # 查看url
    # def get_list_url(self):
    #     url_name = "%s_%s_list" % self.app_model_name
    #     _url = reverse(url_name)
    #
    #     return _url
    #
    # # 添加url
    # def get_add_url(self, obj):
    #     url_name = "%s_%s_add" % self.app_model_name
    #     _url = reverse(url_name, args=(obj.pk,))
    #
    #     return _url


    def get_reverse_url(self, type,obj=None):

        url_name = "%s_%s_%s" % (self.app_label,self.model_name,type)
        if obj:
            _url = reverse(url_name, args=(obj.pk,))
        else:
            _url = reverse(url_name)

        return _url

    #  选择,删除,编辑按钮
    def delete_col(self,obj=None,is_header=False):

        if is_header:
            return "删除"

        return mark_safe("<a href='%s'>删除</a>"%self.get_reverse_url("delete",obj))

    def edit_col(self,obj=None,is_header=False):
        if is_header:
            return "编辑"

        return mark_safe("<a href='%s'>编辑</a>"%(self.get_reverse_url("change",obj)))

    def check_col(self,obj=None,is_header=False):
        if is_header:
            return "选择"

        return mark_safe("<input type='checkbox' name='selected_action' value='%s'>"%obj.pk)


    def get_new_list_display(self):
        new_list_display=[]

        new_list_display.extend(self.list_display)
        if not self.list_display_links:
            new_list_display.append(ModelStark.edit_col)
        new_list_display.append(ModelStark.delete_col)
        new_list_display.insert(0,ModelStark.check_col)

        return new_list_display


    def search_filter(self,request,queryset):
        # search 操作

        key_word = request.GET.get("q")

        print(self.search_fields)  # ["title","price"]
        self.key_word = ""
        if key_word:

            self.key_word=key_word

            search_condition = Q()
            search_condition.connector = "or"
            for field in self.search_fields:
                search_condition.children.append((field + "__icontains", key_word))

            queryset = queryset.filter(search_condition)

        return queryset

    def filter_list(self,request,queryset):
        # filter  操作
        filter_condition = Q()
        for key, val in request.GET.items():  # publish=2&authors=1
            filter_condition.children.append((key, val))
        if filter_condition:
            queryset=queryset.filter(filter_condition)

        return queryset

    def list_view(self,request):


        #  action操作
        if request.method=="POST":
            action=request.POST.get("action")
            pk_list=request.POST.getlist("selected_action")
            queryset=self.model.objects.filter(pk__in=pk_list)

            func=getattr(self,action)

            func(request,queryset)

        # 用户访问的模型表:  self.model
        # print("self.model:", self.model)
        queryset = self.model.objects.all()
        # print("self.list_display", self.list_display)  # ["nid","title","price","publish"]

        # search 操作
        queryset=self.search_filter(request,queryset)

        queryset=self.filter_list(request,queryset)


        showlist=Showlist(self,queryset,request)

        #   获取添加url
        add_url=self.get_reverse_url("add")

        return render(request, "stark/list_view.html", locals())

    def get_model_form_class(self):
        if self.model_form_class:
            return self.model_form_class
        else:
            from django import forms

            class ModelFormDemo(forms.ModelForm):
                class Meta:
                    model = self.model
                    fields = "__all__"

            return ModelFormDemo


    def add_view(self, request):
        """
        if GET请求:
           GET请求:
           form = BookModelForm()
           form:渲染

        if POST请求:
               form = BookModelForm(request.POST)
               form.is_valid()
               form.save()  # 添加数据 create

        :param request:
        :return:
        """
        ModelFormDemo=self.get_model_form_class()

        from  django.forms.boundfield import BoundField
        from  django.forms.models import ModelChoiceField
        if request.method=="GET":
            form=ModelFormDemo()


            for bfield in form :

                # print(type(bfield.field))

                if isinstance(bfield.field,ModelChoiceField):
                    bfield.is_pop=True

                    filed_rel_model=self.model._meta.get_field(bfield.name).rel.to
                    model_name=filed_rel_model._meta.model_name
                    app_label=filed_rel_model._meta.app_label

                    _url=reverse("%s_%s_add"%(app_label,model_name))
                    bfield.url=_url+"?pop_back_id="+bfield.auto_id


            return render(request,"stark/add_view.html",locals())
        else:
            form=ModelFormDemo(request.POST)
            if form.is_valid():
                obj=form.save()
                pop_back_id=request.GET.get("pop_back_id")
                if pop_back_id:
                    pk=obj.pk
                    text=str(obj)
                    return render(request,"stark/pop.html",locals())

                return redirect(self.get_reverse_url("list"))
            else:
                return render(request, "stark/add_view.html", locals())


    def change_view(self, request,id):
       """
        edit_book = Book.objects.get(pk=id)
        GET:
            form = BookModelForm(instance=edit_book)
            form:渲染

        POST:
            form = BookModelForm(request.POST, instance=edit_book)
            form.is_valid
            form.save()  # 更新数据 update
       :param request:
       :param id:
       :return:
       """

       ModelFormDemo=self.get_model_form_class()
       edit_obj=self.model.objects.get(pk=id)
       if request.method=="GET":

           form=ModelFormDemo(instance=edit_obj)
           return render(request, "stark/change_view.html",locals())
       else:
           form=ModelFormDemo(data=request.POST,instance=edit_obj)
           if form.is_valid():
               form.save()
               return redirect(self.get_reverse_url("list"))
           else:
               return render(request, "stark/change_view.html", locals())



    def delete_view(self, request,id):

        if request.method=="POST":
            self.model.objects.get(pk=id).delete()
            return redirect(self.get_reverse_url("list"))

        list_url=self.get_reverse_url("list")
        return render(request,"stark/delete_view.html",locals())


    def get_urls(self):


        temp=[
            url("^$",self.list_view,name="%s_%s_list"%(self.app_model_name)),
            url("^add/$",self.add_view,name="%s_%s_add"%(self.app_model_name)),
            url("^(d+)/change/$",self.change_view,name="%s_%s_change"%(self.app_model_name)),
            url("^(d+)/delete/$",self.delete_view,name="%s_%s_delete"%(self.app_model_name)),

        ]

        return temp


    @property
    def urls(self):


        return self.get_urls(),None,None




class StarkSite(object):

    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)

    # {Book:BookConfig(Book),Publish:ModelAdmin(Publish)}



    def get_urls(self):

        temp = [

        ]

        for model_class, config_obj in self._registry.items():
            print("===>", model_class, config_obj)

            model_name = model_class._meta.model_name
            app_label = model_class._meta.app_label
            print("===>", app_label, model_name,)

            temp.append(url(r'^%s/%s/' % (app_label, model_name),config_obj.urls))

        '''
        创建url:

            url("app01/book/$",self.list_view,name="app01_book_list"),
            url("app01/book/add$",self.add_view,name="app01_book_add"),
            url("app01/book/(d+)/change/$",self.change_view),
            url("app01/book/(d+)/delete/$",self.delete_view),



            url("app01/publish/$",self.list_view,name="app01_publish_list"),
            url("app01/publish/add$",self.add_view,name="app01_publish_add"),
            url("app01/publish/(d+)/change/$",self.change_view),
            url("app01/publish/(d+)/delete/$",self.delete_view),



        '''

        return temp

    @property
    def urls(self):

        return self.get_urls(),None,None

site=StarkSite()
stark.py

utils包里的page.py(分页)

"""
分页组件使用示例:

    obj = Pagination(request.GET.get('page',1),len(USER_LIST),request.path_info)
    page_user_list = USER_LIST[obj.start:obj.end]
    page_html = obj.page_html()

    return render(request,'index.html',{'users':page_user_list,'page_html':page_html})


"""


class Pagination(object):

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

        current_page   start (current_page-1)*per_page_num          end (current_page*per_page_num)
            1            0                                          8
            2            8                                          16
            3            16                                         24

         情况1:self.current_page-self.pager_count_half<1
                2
                3
                5
        pager_start=1
        pager_end=self.pager_count+1


        情况2:
        8 9 10 11 12 13 14 15 16 17 18
        15             20           25


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


        情况3:self.current_page+self.pager_count_half>self.all_pager
             48
             47
             79

        pager_start = self.all_pager-self.pager_count
        pager_end =self.all_pager+1


        """

        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)  # 5
        #
        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_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 = []

        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)



        # self.params       {"page":7,"xxx":123}

        for i in range(pager_start, pager_end):
            self.params["page"]=i
            if i == self.current_page:
                temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, 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)

        return ''.join(page_html_list)
page.py

stark包里的apps.py

from django.apps import AppConfig
from django.utils.module_loading import autodiscover_modules

class StarkConfig(AppConfig):
    name = 'stark'


    def ready(self):
        autodiscover_modules('stark')
apps.py

前端页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">

    <link rel="stylesheet" href="/static/css/commonn.css">
</head>
<body>



{% include "stark/class_form.html" %}


<script>
    function show_option(pop_back_id,pk,text) {
        console.log(pop_back_id,pk,text);

        var option=document.createElement("option");
        option.innerHTML=text;
        option.value=pk;
        option.selected="selected";

        select=document.getElementById(pop_back_id);
        select.appendChild(option);


    }
</script>

</body>
</html>
add_view
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/css/commonn.css">
</head>
<body>

{% include "stark/class_form.html" %}

</body>
</html>
change_view
<div class="container">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">

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

                {% for field in form %}
                    <div class="form-group field_region">
                        <label for="">{{ field.label }}</label>
                        {{ field }} <span class="erorr pull-right">{{ field.errors.0 }}</span>

                        {% if field.is_pop %}
                        <span class="plus"><a onclick="add_option('{{ field.url }}')">+</a></span>
                        {% endif %}

                    </div>
                {% endfor %}


                <input type="submit" class="btn btn-default pull-right">

            </form>
        </div>
    </div>
</div>

<script>
     
    function add_option(url) {

        window.open(url,"","height=500,width=800,top=100,left=100")

    }
    
</script>
class_form
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>


<form action="" method="post">
    {% csrf_token %}
    <input type="submit"  value="确认删除">
    <a href="{{ list_url }}">取消</a>
</form>

</body>
</html>
delete_view
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
    <script src="/static/jquery-3.3.1.min.js"></script>

    <style>
        .table {
            margin-top: 20px;
        }

        .action {
             40%;
            margin-top: 10px;
        }
        .item{
            color: gray;
        }

        .active{
            color: red;
        }
    </style>
</head>
<body>

<h3>数据展示</h3>


<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-1">
            <a href="{{ add_url }}" class="btn btn-success">添加数据</a>
            {% if showlist.conf_obj.search_fields %}
                <form class="form-inline pull-right">
                    <div class="form-group">
                        <div class="input-group">
                            <input type="text" class="form-control" name="q" value="{{ showlist.conf_obj.key_word }}"
                                   placeholder="关键字">
                        </div>
                    </div>
                    <button type="submit" class="btn btn-info">Search</button>
                </form>
            {% endif %}

            <form action="" class="form-inline" method="post">
                {% csrf_token %}
                <select class="form-control action" name="action">
                    <option>-----------------------</option>

                    {% for func_dict in showlist.get_actions %}
                        <option value="{{ func_dict.name }}">{{ func_dict.desc }}</option>
                    {% endfor %}

                </select>
                <input type="submit" class="btn btn-warning" style="vertical-align: -8px">
                <table cl class="table table-bordered table-striped table-hover">
                    <thead>
                    <tr>
                        {% for item in showlist.get_header %}
                            <td>{{ item }}</td>
                        {% endfor %}

                    </tr>
                    </thead>
                    <tbody>
                    {% for data  in showlist.get_body %}
                        <tr>
                            {% for foo in data %}
                                <td>{{ foo }}</td>
                            {% endfor %}
                        </tr>
                    {% endfor %}

                    </tbody>
                </table>
            </form>
            <div>
                <nav aria-label="...">
                    <ul class="pagination">
                        {{ showlist.pagination.page_html|safe }}
                    </ul>
                </nav>
            </div>
        </div>
        <div class="col-md-3">
            <div class="filter_region">
                <div class="alert-info text-center">FILTER</div>

                {% for key,val in showlist.get_filter_links.items %}
                   <div class="panel panel-default">
                      <div class="panel-heading">By {{ key|upper }}</div>
                      <div class="panel-body">
                           {% for link in val %}

                           <p>{{ link|safe }}</p>
                           {% endfor %}

                      </div>
                    </div>
                {% endfor %}

            </div>
        </div>
    </div>
</div>


</body>
</html>
list_view
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>

<h1>POP</h1>

<script>

    window.opener.show_option("{{ pop_back_id }}",'{{ pk }}','{{ text }}');

    window.close();


</script>

</body>
</html>
pop_view



原文地址:https://www.cnblogs.com/lx3822/p/9378471.html