• 基于admin自定义stark组件


    在stark里面代码

    from django.conf.urls import url
    from django.shortcuts import redirect, render
    from django.urls import reverse
    from django.utils.safestring import mark_safe  # 渲染成html页面
    
    
    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)
    
        list_display = ["__str__"]
        list_display_links = []  # 默认的进入编辑,
        model_form_class = []  # 默认的错误提示英文
     
        #  方式1
        # 反向解析出增删改查的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
        #
        #
    
        #  方式2反向解析
        def get_reverse_url(self, type, obj=None):  # obj默认为空,因为我们只拼接了,app和表名  type:代表点击的增删查改
    
            url_name = "%s_%s_%s" % (self.app_label, self.model_name, type)  # 拼接出地址
            if obj:
                _url = reverse(url_name, args=(obj.pk,))  # 把地址传进来,还有有的url是动态的我们可以用一个元祖,把唯一id传进来
            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:
                print(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'>")
    
        def get_new_list_display(self):  # 把上面的放在一个字典里面
            new_list_display = []
    
            new_list_display.extend(self.list_display)
            if not self.list_display_links:  # 如果没有自定义的就用默认编辑, # extend把两个列表里面放一起
                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 list_view(self, request):
            """
            data_list = [
                ["书",122],
    
            ]
            :param request:
            :return:
            """
    
            # 用户访问的模型表:  self.model
            print("self.model:", self.model)
            queryset = self.model.objects.all()
            print("self.list_display", self.list_display)  # ["nid","title","price","publish"]
            # 处理表头
    
            # header_list=["名称","价格","出版社"]
            header_list = []
    
            for field_or_func in self.get_new_list_display():  # ["title","price","publish",delete_col]
    
                if isinstance(field_or_func, str):
    
                    if field_or_func == "__str__":
                        val = self.model._meta.model_name.upper()
                    else:
    
                        field_obj = self.model._meta.get_field(field_or_func)
                        val = field_obj.verbose_name
                #  
    表头怎么定义中文就是中文,不定义就是英文?Verbose_name=“中文”
            新的语法:book._meta.get_field("title")    title可以点里面的字段对象
            现在可以定义了:
    
                else:
                    val = field_or_func(self, is_header=True)
    
                header_list.append(val)
    
            #  处理表单数据
            data_list = []
            for obj in queryset:  # [obj1,obj2,obj3]
                temp = []
    
                for field_or_func in self.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.list_display_links:
                            val = mark_safe("<a href='%s'>%s</a>" % (self.get_reverse_url("change", obj), val))
                    else:
                        val = field_or_func(self, obj)
    
                    temp.append(val)
    
                data_list.append(temp)
    
            print(data_list)
    
            #   获取添加url
            add_url = self.get_reverse_url("add")
    
            return render(request, "stark/list_view.html",
                          {"data_list": data_list, "header_list": header_list, "add_url": add_url})
    
        def get_model_form_class(self):  # 把自定义的提示中文和modelForm封装成函数
            if self.model_form_class:  # 如果有自定义的提示中文
                return self.model_form_class
            else:
                from django import forms
    
                class ModelFormDemo(forms.ModelForm):  # 帮我们把model 字段都转换form里面的字段
                    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()  # 验证get_model_form_class拿到
            if request.method == "GET":
                form = ModelFormDemo()
                return render(request, "stark/add_view.html", locals())  # locals 就是相当于一个元祖传值
            else:
                form = ModelFormDemo(request.POST)
                if form.is_valid():  # 做校验
                    form.save()  # 这个的save相当于create
                    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)  # instance 方法就是决定了是更新还是添加,有就是更新
                if form.is_valid():  # 做校验
                    form.save()  # 这里相当于create
                    return redirect(self.get_reverse_url("list")) # 返回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)),  # 取别名 取别名app+表名是唯一的
                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                                                       #拿到所在的app
                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()   #  这里应用的是一个单例模式,对于AdminSite类的一个单例模式,执行的每一个app中的每一个admin.site都是一个对象
    
    
    整理2
    from django.conf.urls import url
    from django.db.models import Q
    from django.shortcuts import redirect, render
    from django.urls import reverse
    from django.utils.safestring import mark_safe  # 渲染成html页面
    
    from stark.utils.page import Pagination
    
    '''
    封装分页相关数据
            :param current_page: 当前页
            :param all_count:    数据库中的数据总条数
            :param per_page_num: 每页显示的数据条数
            :param base_url: 分页中显示的URL前缀
            :param pager_count:  最多显示的页码个数
    '''
    
    
    class Showlist(object):
        def __init__(self, conf_obj, queryset, request):  # 把配置类对象拿过来,request:从哪里过来的请求,queryset:就是下面showlist传进来的值
            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
    
        # action 批量处理
        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":"批量删除"},]
    
        # filter操作
        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))
    
                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# 判断当前的zd
                    _url = params.urlencode()
    
                    if current_filter_field_id == str(obj.pk):
                        s = "<a class='item active2' 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 = ""  # search 操作设置为空
    
        list_display = ["__str__"]
        list_display_links = []  # 默认的进入编辑,
        model_form_class = []  # 默认的错误提示英文
    
        search_fields = []  # 模糊搜索框
    
        actions = []  # 批量初始化
    
        list_filter = []  # filter   对多对多,多对一 做查询
    
        #  方式1
        # 反向解析出增删改查的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
        #
        #
    
        #  方式2反向解析
        def get_reverse_url(self, type, obj=None):  # obj默认为空
    
            url_name = "%s_%s_%s" % (self.app_label, self.model_name, type)  # 拼接出地址
            if obj:
                _url = reverse(url_name, args=(obj.pk,))  # 把地址传进来,还有有的url是动态的我们可以用一个元祖,把唯一id传进来
            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:
                print(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
    
        #  search 搜索框
        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  # 如果有把值赋给默认的
                # 调用q的另外的一个方法拿到值,不然我们普通循环拿到是字符串
                search_condition = Q()  # 定义一个q所有查询
                search_condition.connector = "or"  # 拿到的值是一个或的关系
                for field in self.search_fields:
                    search_condition.children.append(
                        (field + "__icontains", key_word))  # field+"__icontains"里面包含有key_word有没
                queryset = queryset.filter(search_condition)
    
            return queryset
    
        # FILTER  操作
        def filter_list(self, request, queryset):
            # filter  操作
            filter_condition = Q()
            for key, val in request.GET.items():  # publish=2&authors=1
    
                if key in ["page", "q"]:
                    continue
                filter_condition.children.append((key, val))
            if filter_condition:  # 如果输入不合法
                try:
                    queryset = queryset.filter(filter_condition)
                except Exception:
                    pass
    
            return queryset
    
        def list_view(self, request):
            """
            data_list = [
                ["书",122],
    
            ]
            :param request:
            :return:
            """
    
            # action 批量处理操作
            #  action操作
            if request.method == "POST":
                actions = request.POST.get("action")  # 拿到选择的方法名
                if not actions:
                    pk_list = request.POST.getlist("selected_action")  # 通过getlist 拿到所有的id列表
                    queryset = self.model.objects.filter(pk__in=pk_list)  # 筛选选择的那些id
    
                    func1 = getattr(self, actions)  # 通过方法名拿到对应的方法
    
                    func1(request, queryset)  # 把值传给app01 下的stark 看选择的是哪个
    
            # 用户访问的模型表:  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,然后下面拿到的就是新的
    
            # filter操作
            queryset = self.filter_list(request, queryset)
    
            showlist = Showlist(self, queryset, request)  # Showlist封装成一个类,前端可以通过showlist点方法
    
            #   获取添加url
            add_url = self.get_reverse_url("add")
    
            return render(request, "stark/list_view.html", locals())
    
        def get_model_form_class(self):  # 把自定义的提示中文和modelForm封装成函数
            if self.model_form_class:  # 如果有自定义的提示中文
                return self.model_form_class
            else:
                from django import forms
    
                class ModelFormDemo(forms.ModelForm):  # 帮我们把model 字段都转换form里面的字段
                    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()  # 验证get_model_form_class拿到
    
            from django.forms.models import ModelChoiceField
            if request.method == "GET":
                form = ModelFormDemo()
    
                # pop开始
                for bfield in form:
    
                    # print(type(bfield.field))拿到对象的是什么类型的字段
    
                    if isinstance(bfield.field, ModelChoiceField):  # 用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))  # 反向拿到表和model名字
                        bfield.url = _url + "?pop_back_id=" + bfield.auto_id  # 拼接地址,auto_id 拼接_id 上面的路径
                    # pop结束
    
                return render(request, "stark/add_view.html", locals())  # locals 就是相当于一个元祖传值
            else:
                form = ModelFormDemo(request.POST)
                if form.is_valid():  # 做校验
                    obj = form.save()  # 这个的save相当于create,pop赋值给obj拿到
                    # pop
                    # 判断是不是pop请求弹出框
                    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())
                    # pop 结束
                    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)  # instance 方法就是决定了是更新还是添加,有就是更新
                if form.is_valid():  # 做校验
                    form.save()  # 这里相当于create
                    return redirect(self.get_reverse_url("list"))  # 返回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()
    View Code

    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" %}
    
    <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>
    View Code

    change_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>
    View Code

    class_form_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>
    
    {#                         pop开始#}
                            {% 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>
    View Code

    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>
        <link rel="stylesheet" href="/static/css/commonn.css">
    
    
    </head>
    <body>
    
    <div class="container">
        <div class="row">
            <div class="col-md-3 col-md-offset-3">
                <form action="" method="post">
                    {% csrf_token %}
                    <div class="panel panel-warning">
                        <div class="panel-heading">
                            <h3 class="panel-title">确定删除吗</h3>
                        </div>
                        <div class="panel-body">
                            <input type="submit" class="btn btn-warning" value="确认删除">
                            <a href="{{ list_url }}"class="btn btn-warning">取消</a>
                        </div>
                    </div>
    
                </form>
    
            </div>
        </div>
    </div>
    
    
    </body>
    </html>
    View Code

    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">
        <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
        <script src="/static/jquery-3.3.1.min.js"></script>
        <script src="/static/mystyle.css"></script>
        <link rel="stylesheet" href="/static/css/commonn.css">
        <style>
            .a {
                margin-top: -7px;
            }
    
            .action {
                 40%;
                margin-top: 10px;
            }
    
            .action1 {
    
                margin-top: 10px;
            }
            .item{
                color: gray;
            }
    
            .active2{
                color: red;
            }
        </style>
    
    
    </head>
    <body>
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-md-offset-2">
                <div class="panel panel-warning">
                    <div class="panel-heading">
                        <h3 class="panel-title">
                            <a href="{{ add_url }}" class=" glyphicon glyphicon-plus"></a>
    
                            {#                         search 搜索#}
                            {% if showlist.conf_obj.search_fields %}
                                <form class="form-inline pull-right a ">
                                    <div class="input-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-warning">Search</button>
                                </form>
                            {% endif %}
                            {#                        结束#}
    
                        </h3>
                    </div>
    
                    <form action="" class="form-inline" method="post">
                        {% csrf_token %}
                        <div class="panel-body">
                            <select class="form-control action 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 class="table table-bordered  table-striped action1 ">
                                <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>
                        </div>
                    </form>
    
                </div>
                <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-warning text-center">FILTER</div>
                    {% for key,val in showlist.get_filter_links.items %}
                        <div class="panel panel-warning">
                            <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>
    View Code

    pop

    <!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>
    View Code

    分页

    fromdjango.conf.urlsimporturl
    fromdjango.shortcutsimportredirect,render
    fromdjango.urlsimportreverse
    fromdjango.utils.safestringimportmark_safe#渲染成html页面
    fromstark.utils.pageimportPagination
    
    fromdjango.db.modelsimportQ
    
    
    '''
    封装分页相关数据
    :paramcurrent_page:当前页
    :paramall_count:数据库中的数据总条数
    :paramper_page_num:每页显示的数据条数
    :parambase_url:分页中显示的URL前缀
    :parampager_count:最多显示的页码个数
    '''
    
    classShowlist(object):
    def__init__(self,conf_obj,queryset,request):#把配置类对象拿过来,request:从哪里过来的请求,queryset:就是下面showlist传进来的值
    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]
    
    defget_header(self):
    #处理表头
    #header_list=["名称","价格","出版社"]
    header_list=[]
    
    forfield_or_funcinself.conf_obj.get_new_list_display():#["title","price","publish",delete_col]
    
    ifisinstance(field_or_func,str):
    
    iffield_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)
    returnheader_list
    
    defget_body(self):
    #处理表单数据
    data_list=[]
    forobjinself.page_queryset:#[obj1,obj2,obj3]
    temp=[]
    
    forfield_or_funcinself.conf_obj.get_new_list_display():#list_display=["title","price","publish",delete_col]
    
    ifisinstance(field_or_func,str):
    val=getattr(obj,field_or_func)
    iffield_or_funcinself.conf_obj.list_display_links:
    val=mark_safe("<ahref='%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)
    returndata_list
    
    #action批量处理
    defget_actions(self):
    temp=[]
    forfuncinself.conf_obj.actions:#[patch_delete,]
    temp.append({
    "name":func.__name__,#拿到是函数名
    "desc":func.desc#拿到中文翻译
    })
    
    returntemp#[{"name":"patch_delete","desc":"批量删除"},]
    
    
    
    classModelStark():#默认配置类对象
    
    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=""#search操作设置为空
    
    list_display=["__str__"]
    list_display_links=[]#默认的进入编辑,
    model_form_class=[]#默认的错误提示英文
    
    search_fields=[]#模糊搜索框
    
    actions=[]#批量初始化
    
    #方式1
    #反向解析出增删改查的url
    
    ##删除url
    #defget_delete_url(self,obj):
    #url_name="%s_%s_delete"%self.app_model_name
    #_url=reverse(url_name,args=(obj.pk,))
    #
    #return_url
    #
    ##编辑url
    #defget_change_url(self,obj):
    #url_name="%s_%s_change"%self.app_model_name
    #_url=reverse(url_name,args=(obj.pk,))
    #
    #return_url
    #
    #
    ##查看url
    #defget_list_url(self):
    #url_name="%s_%s_list"%self.app_model_name
    #_url=reverse(url_name)
    #
    #return_url
    #
    ##添加url
    #defget_add_url(self,obj):
    #url_name="%s_%s_add"%self.app_model_name
    #_url=reverse(url_name,args=(obj.pk,))
    #
    #return_url
    #
    #
    
    #方式2反向解析
    defget_reverse_url(self,type,obj=None):#obj默认为空
    
    url_name="%s_%s_%s"%(self.app_label,self.model_name,type)#拼接出地址
    ifobj:
    _url=reverse(url_name,args=(obj.pk,))#把地址传进来,还有有的url是动态的我们可以用一个元祖,把唯一id传进来
    else:
    _url=reverse(url_name)#如果没有动态的,直接拼接地址
    
    return_url
    
    #选择,删除,编辑按钮
    defdelete_col(self,obj=None,is_header=False):
    
    ifis_header:
    return"删除"
    
    returnmark_safe("<ahref='%s'>删除</a>"%self.get_reverse_url("delete",obj))
    
    defedit_col(self,obj=None,is_header=False):
    ifis_header:
    print(is_header)
    return"编辑"
    returnmark_safe("<ahref='%s'>编辑</a>"%(self.get_reverse_url("change",obj)))
    
    defcheck_col(self,obj=None,is_header=False):
    ifis_header:
    return"选择"
    
    returnmark_safe("<inputtype='checkbox'name='selected_action'value='%s'>"%obj.pk)
    
    defget_new_list_display(self):#把上面的放在一个字典里面
    new_list_display=[]
    
    new_list_display.extend(self.list_display)
    ifnotself.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)
    
    returnnew_list_display
    
    
    #search搜索框
    defsearch_filter(self,request,queryset):
    #search操作
    key_word=request.GET.get("q")#拿到搜索框值
    print(self.search_fields)#["title","price"]
    self.key_word=""#判断搜索框里面有没有值
    ifkey_word:
    self.key_word=key_word#如果有把值赋给默认的
    #调用q的另外的一个方法拿到值,不然我们普通循环拿到是字符串
    search_condition=Q()#定义一个q
    search_condition.connector="or"#拿到的值是一个或的关系
    forfieldinself.search_fields:
    search_condition.children.append((field+"__icontains",key_word))#field+"__icontains"里面包含有key_word有没
    queryset=queryset.filter(search_condition)
    
    returnqueryset
    
    
    deflist_view(self,request):
    """
    data_list=[
    ["书",122],
    
    ]
    :paramrequest:
    :return:
    """
    
    #action批量处理操作
    #action操作
    ifrequest.method=="POST":
    actions=request.POST.get("action")#拿到选择的方法名
    pk_list=request.POST.getlist("selected_action")#通过getlist拿到所有的id列表
    queryset=self.model.objects.filter(pk__in=pk_list)#筛选选择的那些id
    
    func1=getattr(self,actions)#通过方法名拿到对应的方法
    
    func1(request,queryset)#把值传给app01下的stark看选择的是哪个
    
    #用户访问的模型表: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,然后下面拿到的就是新的
    
    showlist=Showlist(self,queryset,request)#Showlist封装成一个类,前端可以通过showlist点方法
    
    #获取添加url
    add_url=self.get_reverse_url("add")
    
    returnrender(request,"stark/list_view.html",locals())
    
    defget_model_form_class(self):#把自定义的提示中文和modelForm封装成函数
    ifself.model_form_class:#如果有自定义的提示中文
    returnself.model_form_class
    else:
    fromdjangoimportforms
    
    classModelFormDemo(forms.ModelForm):#帮我们把model字段都转换form里面的字段
    classMeta:
    model=self.model
    fields="__all__"
    
    returnModelFormDemo
    
    defadd_view(self,request):
    """
    ifGET请求:
    GET请求:
    form=BookModelForm()
    form:渲染
    
    ifPOST请求:
    form=BookModelForm(request.POST)
    form.is_valid()
    form.save()#添加数据create
    
    :paramrequest:
    :return:
    """
    ModelFormDemo=self.get_model_form_class()#验证get_model_form_class拿到
    ifrequest.method=="GET":
    form=ModelFormDemo()
    returnrender(request,"stark/add_view.html",locals())#locals就是相当于一个元祖传值
    else:
    form=ModelFormDemo(request.POST)
    ifform.is_valid():#做校验
    form.save()#这个的save相当于create
    returnredirect(self.get_reverse_url("list"))
    else:
    returnrender(request,"stark/add_view.html",locals())
    
    defchange_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
    :paramrequest:
    :paramid:
    :return:
    """
    
    ModelFormDemo=self.get_model_form_class()
    edit_obj=self.model.objects.get(pk=id)
    ifrequest.method=="GET":
    
    form=ModelFormDemo(instance=edit_obj)
    returnrender(request,"stark/change_view.html",locals())
    else:
    form=ModelFormDemo(data=request.POST,instance=edit_obj)#instance方法就是决定了是更新还是添加,有就是更新
    ifform.is_valid():#做校验
    form.save()#这里相当于create
    returnredirect(self.get_reverse_url("list"))#返回list
    else:
    returnrender(request,"stark/change_view.html",locals())
    
    defdelete_view(self,request,id):
    
    ifrequest.method=="POST":
    self.model.objects.get(pk=id).delete()
    returnredirect(self.get_reverse_url("list"))
    
    list_url=self.get_reverse_url("list")
    returnrender(request,"stark/delete_view.html",locals())
    
    defget_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)),
    
    ]
    
    returntemp
    
    @property
    defurls(self):
    
    returnself.get_urls(),None,None
    
    
    classStarkSite(object):
    
    def__init__(self,name='admin'):
    self._registry={}
    
    defregister(self,model,admin_class=None,**options):
    ifnotadmin_class:
    admin_class=ModelStark#配置类
    
    self._registry[model]=admin_class(model)
    
    #{Book:BookConfig(Book),Publish:ModelAdmin(Publish)}
    
    defget_urls(self):
    
    temp=[
    
    ]
    
    formodel_class,config_objinself._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),
    
    
    
    '''
    
    returntemp
    
    @property
    defurls(self):
    
    returnself.get_urls(),None,None
    
    
    site=StarkSite()
    View Code

  • 相关阅读:
    ADT Android Development Tools
    ADT下载地址(含各版本)
    如何在eclipse中添加android ADT
    3D MAX 人物骨骼建设
    如何绕开验证码(原理)
    二分查找 java
    Linux命令 cat命令
    Linux如何通过命令查看日志文件的某几行(中间几行或最后几行)
    Linux中显示一个文件最后几行的命令
    深入理解SQL的四种连接-左外连接、右外连接、内连接、全连接
  • 原文地址:https://www.cnblogs.com/maojiang/p/9395838.html
Copyright © 2020-2023  润新知