Python入门自学进阶-Web框架——22DjangoAdmin项目应用-定制页面

Posted kaoa000

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python入门自学进阶-Web框架——22DjangoAdmin项目应用-定制页面相关的知识,希望对你有一定的参考价值。

使用Django Admin,所有用户登录后的页面都是一堆表,现在想做成自己想要的样式,如不同的人登录,根据权限,显示不同的菜单项和不同的首页。

根据不同的人,渲染不同的内容。

一、下载一个网站的模板,bootstrap-4.6.1-examples中的dashboard

共三个文件:

将index.html拷贝到templates目录下

在/static目录下创建css、js子目录,将需要的css、js文件拷贝进去,通过index.html分析,主要涉及以下文件 :上图的dashboard.css和dashboard.js,这是模板的样式文件和js文件,还需要一些支持文件,bootstrap.min.css、bootstrap.bundle.min.js、bootstrap.min.js、chart.min.js、feather.js等。

二、建立应用单独的urls:

在项目的urls中增加:path('plcrm',include("plcrm.urls")),

在应用下建立urls.py:

from django.urls import path
from plcrm import views

urlpatterns = [
    path('/', views.index),
]

建立根页面路径,即访问http://127.0.0.1/plcrm/访问的页面

 删除一些菜单和数据:

 三、登录显示,将Sign out处用request.user代替,因为使用的是Django admin,admin登录了,这里的request.user就是登录的用户。当我们用root登录时,这里显示的就是root。

四、实现登录后的权限跟随,即不同人员登录,显示不同的菜单项:

这是一个用户、角色、菜单项的联动操作。

1、首先登录使用的是User中维护的用户,这是admin的登录用户表,我们是借助admin的登录功能。这个表与我们自定义的UserProfile表关联,我们实际的用户名在UserProfile表的name中,所以上面的登录显示用户最好是写成 request.user.userprofile.name ,这样就显示我们录入的名字。

2、UserProfile表又跟Roles表关联,也就是UserProfile表中保存了对应用户的角色,当然,一个用户可以有多个角色。

3、Roles角色表又跟菜单项表Menus关联,即一个角色可以访问哪些菜单项。

4、最后是单独的菜单项表,维护着不同的菜单项。

在维护上要从后向前维护

1、先定义不同的菜单项:

一共增加了3个:

 名字就是在前端页面显示的菜单项的名称,自己根据实际情况任意编写的,重点是这里的url_name,这是在urls.py中定义的:

 实际上就是路由项的别名,根据这个名字,在前端就能生成资源的url,在后端就能找到对应的视图函数。

2、维护角色,对不同角色赋予不同的菜单项,也就是赋予不同的权限

如定义一个超级管理员:三个菜单项都能访问到

 

3、维护用户,先维护admin的User用户,即维护登录用户,定义了三个用户

 然后维护我们自己定义的UserProfile用户表

这样,超级用户拥有超级管理员角色,可以访问全部三个资源,销售人员拥有销售角色,可以访问销售和客户两个资源,学生王一拥有学生角色,只能访问学生资源。

4、针对URL,编写视图函数:

from django.shortcuts import render

# Create your views here.

def index(req):
    return render(req,"index.html")

def student_index(req):
    return render(req,"student/student_index.html")

def cust_index(req):
    return render(req,"cust/cust_index.html")

前端:base.html

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="">
    <meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors">
    <meta name="generator" content="Hugo 0.88.1">
    <title>自定制 Dashboard Template · Bootstrap v4.6</title>

    <!-- Bootstrap core CSS -->
<link href="/static/css/bootstrap.min.css" rel="stylesheet">

    <style>
      .bd-placeholder-img 
        font-size: 1.125rem;
        text-anchor: middle;
        -webkit-user-select: none;
        -moz-user-select: none;
        -ms-user-select: none;
        user-select: none;
      

      @media (min-width: 768px) 
        .bd-placeholder-img-lg 
          font-size: 3.5rem;
        
      
    </style>

    <!-- Custom styles for this template -->
    <link href="/static/css/dashboard.css" rel="stylesheet">
  </head>
% block mybody %
% endblock %
</html>

index.html

% extends "base.html" %
% block mybody %
<body>
    
<nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0 shadow">
  <a class="navbar-brand col-md-3 col-lg-2 mr-0 px-3" href="#">我的客户管理系统</a>
  <button class="navbar-toggler position-absolute d-md-none collapsed" type="button" data-toggle="collapse" data-target="#sidebarMenu" aria-controls="sidebarMenu" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>
  <!-- input class="form-control form-control-dark w-100" type="text" placeholder="Search" aria-label="Search" -->
  <ul class="navbar-nav px-3">
    <li class="nav-item text-nowrap">
      <a class="nav-link" href="#"> request.user.userprofile.name </a>
    </li>
  </ul>
</nav>

<div class="container-fluid">
  <div class="row">
    <nav id="sidebarMenu" class="col-md-3 col-lg-2 d-md-block bg-light sidebar collapse">
      <div class="sidebar-sticky pt-3">
        <ul class="nav flex-column">
          % for role in request.user.userprofile.roles.all %
            % for menu in role.menus.all %
                <li class="nav-item">
                <a class="nav-link active" href="%  url menu.url_name %">
              <span data-feather="home"></span>
                     menu.name  <span class="sr-only">(current)</span>
            </a>
          </li>
            % endfor %

          % endfor %

        </ul>
      </div>
    </nav>

    <main role="main" class="col-md-9 ml-sm-auto col-lg-10 px-md-4">
    % block page-content %
      <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
        <h1 class="h2">Dashboard</h1>
        <div class="btn-toolbar mb-2 mb-md-0">
          <div class="btn-group mr-2">
            <button type="button" class="btn btn-sm btn-outline-secondary">Share</button>
            <button type="button" class="btn btn-sm btn-outline-secondary">Export</button>
          </div>
          <button type="button" class="btn btn-sm btn-outline-secondary dropdown-toggle">
            <span data-feather="calendar"></span>
            This week
          </button>
        </div>
      </div>

      <canvas class="my-4 w-100" id="myChart" width="900" height="380"></canvas>

      <h2>Section title</h2>
      <div class="table-responsive">

      </div>
        % endblock %
    </main>

  </div>
</div>


    <script src="/static/js/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
      <script>window.jQuery || document.write('<script src="/static/js/jquery.slim.min.js"><\\/script>')</script><script src="/static/js/bootstrap.bundle.min.js"></script>

      
        <script src="/static/js/feather.4.28.min.js"></script>
        <script src="/static/js/Chart.2.9.4.min.js"></script>
        <script src="/static/js/dashboard.js"></script>
  </body>
% endblock %

这个前端页面中,主要注意for循环的写法,request.user.userprofile.roles.all是获取用户全部角色,使用admin的用户系统,前端就能获得用户信息,即request.user,又根据关联性,可以依次找到userprofile和roles,最终获得此用户的全部角色。然后再遍历每个角色的menu,即找到菜单项,显示出来。

cust_index.html

% extends "index.html" %

% block page-content %
    客户首页
% endblock %

student_index.html

% extends "index.html" %

% block page-content %
    学生页面首页
% endblock %

当以root登录时:

以user01登录时:

以user02登录:

以上就实现了用户、角色、权限的联动。

存在的问题:

两个角色如果有相同的菜单项,并且这两个角色被赋给同一用户,菜单显示会重复;

在地址栏中直接输入资源url,也能访问页面上不存在的菜单项。 

五、实现表的展现

类似DjangoAdmin中一个表的展现方式。要做成通用的,所以单独做成一个APP,即单独一个应用。

添加新的APP,第一种方法在pycharm中找到tools——>run manage.py task...,然后在窗口中直接输入startapp appname

第二种方法是在终端运行:python manage.py startapp appname

创建后,需要在settings中增加app名称:

看pycharm自动创建的APP,其增加的是   'appname.apps.PlcrmConfig',,但在网上看到很多都是直接写appname,这里用'appname.apps.PlcrmConfig'试试。

以上是关于Python入门自学进阶-Web框架——22DjangoAdmin项目应用-定制页面的主要内容,如果未能解决你的问题,请参考以下文章

Python入门自学进阶-Web框架——18FormModelForm

Python入门自学进阶-Web框架——20Django其他相关知识2

Python入门自学进阶-Web框架——2Django初识

Python入门自学进阶-Web框架——3Django的URL配置

Python入门自学进阶-Web框架——21DjangoAdmin项目应用

Python入门自学进阶-Web框架——21DjangoAdmin项目应用