zoukankan      html  css  js  c++  java
  • 自定义django admin及其界面

    1.在项目目录下新创建一个app,命名为kingadmin,在templates目录下新建kingadmin目录,用来存放相关页面的模板文件,新建一个templatetags目录,用来存放处理前端模板数据的python函数。

    项目/kingadmin/templates/kingadmin/base.html   最基础的模板,存放的js与css

    <!DOCTYPE html>
    <html lang="zh-CN">
        <head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
        <meta name="description" content="">
        <meta name="author" content="">
    {#    meta全部保留,IE浏览器相关的可要可不要,图标与css也要全部保留#}
        <link rel="icon" href="http://v3.bootcss.com/favicon.ico">
        <title>王腾的个人站点</title>
        <link href="/static/css/bootstrap.min.css" rel="stylesheet">
        <link href="/static/css/dashboard.css" rel="stylesheet">
         {% block header-resources %} {% endblock %}
    {#    这里留一个block块,可以方便其他网页继承时进行扩展 来添加自定义样式#}
      </head>
    
      <body>
        {% block body %} {% endblock %}
    {#     这里留一个block  body块,可以方便其他网页继承时进行扩展 在body里添加自定义的内容#}
        <script src="/static/js/jquery.min.js"></script>
        <script src="/static/js/bootstrap.min.js"></script>
        <script src="/static/js/holder.min.js"></script>
    {#    这些js全部保留,js的路径static是settings.py中STATIC_URL = '/static/'对应的STATIC_URL,而不是实际的目录名#}
        <script>
    {#        这里是自定义js,点击相应按钮时,按钮变颜色#}
            $(document).ready(function () {
                var current_url = "{{ request.path }}";
                $('.nav-sidebar a[href="{{ request.path }}"]').parent().addClass('active');
            })
        </script>
    </body></html>
    View Code

    项目/kingadmin/templates/kingadmin/index.html  页面框架

    {% extends 'base.html' %}
    {#这里写继承base.html#}
    {% block body %}
    {#    这里在block body里自定义body的内容,要注意写上block body#}
        {% block nav-bar %}
    {#        这个block块是页面最上边的导航栏,为了其他页面可自定制导航栏,这里弄一个块,当其它页面写上 {% block nav-bar %}{% endblock %}时#}
    {#        其它页面的导航栏位置就不会显示模板的导航栏了#}
        <nav class="navbar navbar-inverse navbar-fixed-top">
          <div class="container-fluid">
            <div class="navbar-header">
              <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
              </button>
              <a class="navbar-brand" href="http://v3.bootcss.com/examples/dashboard/#">后台管理</a>
            </div>
            <div id="navbar" class="navbar-collapse collapse">
              <ul class="nav navbar-nav navbar-right">
                <li><a href="http://v3.bootcss.com/examples/dashboard/#">Dashboard</a></li>
                <li><a href="http://v3.bootcss.com/examples/dashboard/#">Settings</a></li>
                <li><a href="http://v3.bootcss.com/examples/dashboard/#">Profile</a></li>
                <li class="dropdown">
    {#                这里添加一个下拉菜单,也是找的模板上的#}
                    <a href="http://v3.bootcss.com/examples/dashboard/#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{{ request.user.userprofile.name }}<span class="caret"></span></a>
                    <ul class="dropdown-menu">
                      <li><a href="http://v3.bootcss.com/examples/dashboard/#">首页</a></li>
                      <li><a href="/logout">注销</a></li>
                    </ul>
                  </li>
              </ul>
              <form class="navbar-form navbar-right">
                <input type="text" class="form-control" placeholder="Search...">
              </form>
            </div>
          </div>
        </nav>
        {% endblock %}
        <div class="container-fluid">
          <div class="row">
              {% block side-bar %}
    {#              这里写一个左边栏block块,也是为了其他页面可以自定制#}
            <div class="col-sm-3 col-md-2 sidebar">
              <ul class="nav nav-sidebar">
                  {% block side-bar-menu %}
                      {% for role in request.user.userprofile.roles.all %}
                          <h3></h3>
    {#                      <li class="active"><a href="http://v3.bootcss.com/examples/dashboard/#">{{ role }}<span class="sr-only">(current)</span></a></li>#}
                          {% for menu in role.menus.all %}
                              <li>
                                  <a href="{% if menu.url_type == 0 %}{% url menu.url_name  %}{% else %}{{ menu.url_name }}
    {#                              这里的{% url menu.url_name  %}就是取得数据库中的url_name,并且将这个url_name与urls.py中的name做比较,相同才可以跳转到相应页面,#}
                                      {% endif %}">{{ menu.name }}</a>
                              </li>
                          {% endfor %}
                      {% endfor %}
                  {% endblock %}
              </ul>
            </div>
              {% endblock %}
          {% block right-container %}
            <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
            {% block right-container-content %}
              <h1 class="page-header">Dashboard</h1>
              <div class="row placeholders">
                <div class="col-xs-6 col-sm-3 placeholder">
                  <img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
                  <h4>Label</h4>
                  <span class="text-muted">Something else</span>
                </div>
                <div class="col-xs-6 col-sm-3 placeholder">
                  <img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
                  <h4>Label</h4>
                  <span class="text-muted">Something else</span>
                </div>
                <div class="col-xs-6 col-sm-3 placeholder">
                  <img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
                  <h4>Label</h4>
                  <span class="text-muted">Something else</span>
                </div>
                <div class="col-xs-6 col-sm-3 placeholder">
                  <img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
                  <h4>Label</h4>
                  <span class="text-muted">Something else</span>
                </div>
              </div>
              <h2 class="sub-header">Section title</h2>
            {% endblock %}
            </div>
              {% endblock %}
          </div>
        </div>
    {% endblock %}
    View Code

    项目/kingadmin/templates/kingadmin/app_index.html  app页面

    {% extends 'kingadmin/index.html' %}
    {% load kingadmin_tags %}
    {#这里要使用tags的原因是:前端模板不允许变量有下划线,但是为了获得表名,python函数_mtea是有下划线的,所有要用tags#}
    {% block right-container-content %}
        {% for app,app_tables in size.registered_sites.items %}
            <table class="table table-hover">
                <thead>
                    <tr>
                        <h3>{{ app }}</h3>
                    </tr>
                </thead>
                  <tbody>
                    {% for model_name,admin_class in app_tables.items %}
                        <tr>
                           {#这里设置相关链接的url,这里要使用tags的原因是:前端模板不允许变量有下划线,但是为了获得表名,python函数_mtea是有下划线的,所有要用tags#}
                          <th scope="row"><a href="/kingadmin/{% get_app_name admin_class.model %}/{% get_model_name admin_class.model %}">{% get_model_verbose_name admin_class.model %}</a>  {{ admin_class }}</th>
                        </tr>
                    {% endfor %}
                  </tbody>
            </table>
        {% endfor %}
    {% endblock %}
    View Code

    项目/kingadmin/templates/kingadmin/table_data_list.html  每张表的详细展示页面

    {% extends 'kingadmin/index.html' %}
    {% load kingadmin_tags %}
    {% block right-container-content %}
         <h4>{% get_model_verbose_name admin_obj.model  %}</h4>
            <table class="table table-hover">
                <thead>
                    <tr>
    {#                    aadmin_obj其实就是注册表的表对象,在views函数里#}
                        {% for column in admin_obj.list_display %}
                            <th>{{ column }}</th>
                        {% endfor %}
                    </tr>
                </thead>
                  <tbody>
                        {% for obj in admin_obj.querysets %}
                            <tr>
                                {%  build_table_row admin_obj obj %}
                            </tr>
                        {% endfor %}
                  </tbody>
            </table>
    {% endblock %}
    View Code

    项目/kingadmin/templatetags/kingadmin_tags.py  标签函数,用来存放处理前端数据的标签函数

    #!/usr/bin/python
    # -*- coding:utf-8 -*-
    # author:wt
    
    from django import template
    from django.utils.safestring import mark_safe
    register = template.Library()
    
    @register.simple_tag
    def get_model_verbose_name(model_obj):  # 获取表的中文名,
        model_name = model_obj._meta.verbose_name if model_obj._meta.verbose_name else model_obj._meta.verbose_name_plural
        if not  model_name:
            model_name = model_obj._meta.model_name
        print('ssss',model_name)
        return model_name
    
    @register.simple_tag
    def get_app_name(model_obj):
        print('label',model_obj._meta.app_label)
        return model_obj._meta.app_label  # 获取app名
    
    @register.simple_tag
    def get_model_name(model_obj):   # 获取表的英文名,
        print('model_name',model_obj._meta.model_name)
        return model_obj._meta.model_name
    
    @register.simple_tag
    def build_table_row(admin_obj,obj):  # 在前端显示表格详细内容
        row_ele = ''
        for column in admin_obj.list_display:
            column_obj = obj._meta.get_field(column)  # 获取字段的对象形式
            if column_obj.choices:  #判断column_obj是否是表中的choice字段,用choice属性,如果是choice字段,则返回真
                get_column_data = getattr(obj,'get_%s_display'%column)
                column_data = get_column_data()
            else:
                column_data = getattr(obj,column)  #获取对象obj的属性column对应的值,这里的column就是表中的字段
            td_ele = """<td>%s""" % column_data
            row_ele += td_ele
        return mark_safe(row_ele)
    View Code

    2.以下函数全都创建在项目/kingadmin/下
    app_config.py   自动找到settings.py文件,并将其中的app模块全部导入

    #!/usr/bin/python
    # -*- coding:utf-8 -*-
    # author:wt
    from django import conf  # 导入conf模块
    
    conf.settings  # 可以自动找到项目的配置文件
    
    for app in conf.settings.INSTALLED_APPS:
        try:
            print(__import__('%s.kingadmin' % app))  # 自动导入相关模块
        except ImportError as e:
            print('app has no import')
    View Code

    base_admin.py  主要的admin函数

    #!/usr/bin/python
    # -*- coding:utf-8 -*-
    # author:wt
    
    class AdminRegisterException(Exception):  # 处理注册app时发生异常
        def __init__(self,msg):
            self.message = msg
    
    
    class BaseAdmin(object):  # 定义过滤条件,就是如果将表中的部分字段写在下边的括号里,那么将按这几个字段进行过滤,如:list_display = ('qq','name'),按qq和name过滤
        list_display = ()
        list_filter = ()
        search_fields = ()
        list_editable = ()
    
    
    class AdminSite(object):
        def __init__(self):
            self.registered_sites = {}
    
        def registed(self,model,admin_class=None):
            app_name = model._meta.app_label  # 获取app名
            model_name = model._meta.model_name  # 获取app的表名
    
            if app_name not in self.registered_sites:
                self.registered_sites[app_name] = {}
    
            if model_name in self.registered_sites[app_name]:
                raise AdminRegisterException("app [%s] model [%s] has already registerred!" % (app_name,model_name))
            if not admin_class:
                #则使用BaseAdmin
                admin_class = BaseAdmin
            admin_obj = admin_class()  # 实例化
            admin_obj.model = model  # 再给BaseAdmin类添加一个属性model,这样就可以获取到表的model对象了,进而可以通过model._meta.verbose_name获取到表的中文名了
    
            self.registered_sites[app_name][model_name] = admin_obj  # 将表对象放进字典
    
    
    site = AdminSite()
    View Code

    views.py   数据处理函数

    from django.shortcuts import render
    from django import conf
    from kingadmin import app_config
    from kingadmin import base_admin
    # Create your views here.
    def app_index(request):
        print(base_admin.site.registered_sites)
        return render(request,'kingadmin/app_index.html',{'size':base_admin.site})
    
    
    def table_data_list(request,app_name,model_name):
        admin_obj = base_admin.site.registered_sites[app_name][model_name]  # admin_obj其实就是注册表的表对象
        admin_obj.querysets = admin_obj.model.objects.all()  # 给admin_obj添加自定义属性querysets
        return render(request,'kingadmin/table_data_list.html',locals()) # locals()返回全部的admin_obj,
    View Code

    urls.py  路由函数

    from django.conf.urls import url,include
    from django.contrib import admin
    from kingadmin import views
    
    urlpatterns = [
        # url(r'^', views.dashboard),
        url(r'^$', views.app_index),
        url(r'^(w+)/(w+)/$', views.table_data_list),
    ]
    View Code
  • 相关阅读:
    甲午年总结
    浅谈数字营销
    机器学习笔记
    上海GDG活动有感
    我也谈谈游戏
    CSS3新增属性
    js事件详解
    DOM与BOM相关操作
    JS基础知识
    js数据类型
  • 原文地址:https://www.cnblogs.com/wt11/p/6609541.html
Copyright © 2011-2022 走看看