Django Admin 后台自定制技巧


Django最強大的部分之一是自動管理界面。它從模型中讀取元數據,以提供一個快速的,以模型為中心的界面,受信任的用戶可以在其中管理您網站上的內容。管理員的建議用法僅限於組織的內部管理工具。它並非旨在構建您的整個前端。

Django Admin 簡單配置

settings.py

LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'

models.py

from django.db import models
import sqlite3
from django.utils.html import format_html

STATUS_CHOICES = (('d', '正常'),('p', '警告'),('w', '損壞'),)

class HostDB(models.Model):
    id = models.AutoField(primary_key=True)
    hostname = models.CharField(max_length=64,verbose_name="主機名稱")
    hostaddr = models.TextField(max_length=64,verbose_name="主機地址")
    hostCPU = models.CharField(max_length=64,verbose_name="主機CPU")
    hostMEM = models.CharField(max_length=64,verbose_name="主機內存")
    DataTime = models.DateTimeField(verbose_name="主機當前時間")
    hostUser = models.CharField(max_length=64,verbose_name="負責人")
    hostStats = models.CharField(max_length=1,choices=STATUS_CHOICES,verbose_name="狀態")

    def __str__(self):
        return self.hostname
    # 自定義方法,主要負責給主機標注顏色
    def Status(self):
        if self.hostStats == 'd':
            format_td = format_html('<span style="padding:2px;background-color:green;color:white">正常</span>')
        elif self.hostStats == 'p':
            format_td = format_html('<span style="padding:2px;background-color:yellow;color:black">警告</span>')
        elif self.hostStats == 'w':
            format_td = format_html('<span style="padding:2px;background-color:red;color:white">損壞</span>')
        return format_td
    Status.short_description = "當前狀態"

admin.py

from django.contrib import admin
from MyWeb.models import *

# 必須繼承ModelAdmin基類,才可以調整參數,HostDB則是你的表的名稱
@admin.register(HostDB)
class MyAdmin(admin.ModelAdmin):
    admin.site.site_title="自動化后台管理"
    admin.site.site_header = "Django 自動化運維"

    # list_display = 你需要展示的字段應該寫在這里,此處是數據庫中的字段
    list_display = ("hostname","hostaddr","hostCPU","hostMEM","DataTime","hostUser","Status")
    # search_fields = 用於添加一個搜索框,此處以hostaddr作為查詢條件
    search_fields = ("hostaddr",)
    # list_filter = 設置一個過濾器,此處是以hostname作為過濾條件
    list_filter = ("hostname",)
    # ordering = 設置一個排序條件,此處是以id作為排序依據
    ordering = ("id",)
    #list_per_page = 設置每頁顯示多少條記錄,默認是100條
    list_per_page = 10
    #list_editable = 設置默認可編輯字段
    #list_editable = ("DataTime",)
    # date_hierarchy = 顯示詳細時間分層篩選
    date_hierarchy = 'DataTime'
    # readonly_fields = 可以設置只讀字段,就是無法修改的字段
    readonly_fields = ("hostCPU","hostMEM",)

python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser

效果如下。

另外找到一個不錯的主題

pip install simpleui

vim settings.py
INSTALLED_APPS = [
    'simpleui',
    'django.contrib.admin',
    'myweb.apps.MywebConfig',
]

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

定制主機管理菜單

vim settings.py
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'

apps.py
from django.apps import AppConfig
class MywebConfig(AppConfig):
    name = 'MyWeb'
    verbose_name = "服務器集群"

models.py

from django.db import models
from django.utils.html import format_html

STATUS_CHOICES = (('d', '正常'),('p', '警告'),('w', '損壞'),)

class HostInfo(models.Model):
    id = models.AutoField(primary_key=True)
    HostName = models.CharField(max_length=64,verbose_name="主機名")
    HostAddr = models.CharField(max_length=64,verbose_name="主機IP")
    HostModel = models.CharField(max_length=64,verbose_name="設備型號")
    HostCPU = models.CharField(max_length=64,verbose_name="主機CPU")
    HostMem = models.CharField(max_length=64,verbose_name="主機內存")
    HostDisk = models.CharField(max_length=64,verbose_name="主機磁盤")
    HostSys = models.CharField(max_length=64,verbose_name="操作系統")
    HostZone = models.CharField(max_length=64,verbose_name="區域")
    DataTime = models.DateField(max_length=64,verbose_name="統計時間")
    HostPeple = models.CharField(max_length=64, verbose_name="負責人")
    HostStats = models.CharField(max_length=1,choices=STATUS_CHOICES,verbose_name="狀態")

    def __str__(self):
        return self.HostName
    # 用於給本表指定一個別名
    class Meta():
        verbose_name = "Web前台集群"
        verbose_name_plural= "Web前台集群"
    # 自定義方法,主要負責給主機標注顏色
    def Status(self):
        if self.HostStats == 'd':
            format_td = format_html('<span style="padding:2px;background-color:green;color:white">正常</span>')
        elif self.HostStats == 'p':
            format_td = format_html('<span style="padding:2px;background-color:yellow;color:black">警告</span>')
        elif self.HostStats == 'w':
            format_td = format_html('<span style="padding:2px;background-color:red;color:white">損壞</span>')
        return format_td
    Status.short_description = "狀態"

admin.py

from django.contrib import admin
from MyWeb.models import *

# 必須繼承ModelAdmin基類,才可以調整參數,HostDB則是你的表的名稱
@admin.register(HostInfo)
class MyAdmin(admin.ModelAdmin):
    admin.site.site_title="自動化后台管理"
    admin.site.site_header = "Django 自動化運維"

    # list_display = 你需要或者想要展示在頁面中的字段
    list_display = ("HostName","HostAddr","HostModel","HostCPU","HostMem","HostDisk","HostSys","HostZone","DataTime","HostPeple","Status")
    # search_fields = 添加搜索功能,並以HostName作為搜索條件
    search_fields = ("HostName",)
    # ordering = 設置以HostAddr作為排序條件
    ordering = ("HostAddr",)
    # list_per_page = 設置每頁顯示的字段數
    list_per_page = 10

自定義頁面功能

在templates中新建一個名稱為lyshark.html的文件

{% extends "admin/base_site.html" %}
{% load i18n static %}
{% load static %}
{% block title %}{{ site_title|default:_('Django site admin') }}{% endblock %}

{% block content %}
 <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
    <script>
    $(".breadcrumbs").append("&nbsp;&nbsp;<a href=\"/admin/\">儀表盤</a>");
    $(".breadcrumbs").append("&nbsp;&nbsp;<a href=\"/admin/\">主機監控</a>");
    $(".breadcrumbs").append("&nbsp;&nbsp;<a href=\"/admin/\">命令執行</a>");
    $(".breadcrumbs").append("&nbsp;&nbsp;<a href=\"/admin/\">圖表繪制</a>");
    $(".breadcrumbs").append("&nbsp;&nbsp;<a href=\"/admin/\">批量CMD</a>");
    </script>

    <form action="/lyshark/" method="post">
       用戶:<input type="text" value="text">
        密碼:<input type="text" value="text">
        <input type="text" value="text">
        <input type="text" value="text">

        <input type="submit" value="提交表單">
    </form>
{% endblock %}

接着在view.py中增加一條視圖函數

from django.shortcuts import render
from django.contrib.auth.decorators import login_required

@login_required(login_url="/admin/login")
def lyshark(request):
    return render(request,"lyshark.html")

最后別忘了在urls.py里面添加映射記錄.

from MyWeb import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path("lyshark/",views.lyshark)
]

上方添加了裝飾器,函數,只有用戶登陸后才可以訪問到定制頁面,如果沒有登陸則提示需要登陸,這樣更加靈活了。

添加各種標志

添加已過期標志: 判斷當前時間是否與數據庫時間一致,並顯示過期狀態.

# name: admin.py
from django.contrib import admin
from MyWeb.models import *
@admin.register(HostDB)
class MyAdmin(admin.ModelAdmin):
    list_display = ("id","date","Status")

# name: models.py
from django.db import models
from django.utils.html import format_html
import datetime

class HostDB(models.Model):
    id = models.AutoField(primary_key=True)
    date = models.CharField(max_length=64)
    def Status(self):
        NowData = datetime.date.today()
        if self.date >= str(NowData):
            ret = "未過期"
            color = "green"
            return format_html('<span style="color:{};">{}</span>',color,ret,)
        else:
            ret = "已過期"
            color = "red"
            return format_html('<span style="color:{};">{}</span>', color, ret,)
    Status.short_description = "是否過期"

添加進度條展示 琢磨了一下,把進度條也堆上了。呵呵

# name: admin.py
from django.contrib import admin
from MyWeb.models import *

@admin.register(HostDB)
class MyAdmin(admin.ModelAdmin):
    list_display = ("id","Count","Speed")

# name: models.py
from django.db import models
from django.utils.html import format_html

class HostDB(models.Model):
    id = models.AutoField(primary_key=True)
    Count = models.IntegerField()

    def Speed(self):
        return format_html('<progress max="100" value="{}"></progress>',self.Count)
    Speed.short_description = "當前進度"

實現查看標簽 添加一個查看標簽

    def Check(self):
        return format_html('<a href="/admin/MyWeb/hostdb/{}/change/">查看</a>',self.id)

增加自定義actions: 自定義Action標簽,Action標簽就是Admin頁面中左上角的橫線部分,我們自己增加新的.

# name: admin.py
from django.contrib import admin
from MyWeb.models import *

# 必須繼承ModelAdmin基類,才可以調整參數,HostDB則是你的表的名稱
@admin.register(HostInfo)
class MyAdmin(admin.ModelAdmin):
    admin.site.site_title="自動化后台管理"
    admin.site.site_header = "Django 管理平台"
    <省略部分...>
    def func(self,request,queryset):
        # 此處可以寫一些執行動作
        print(self,request,queryset)
    func.short_description = "自定義active動作"
    actions = [func,]
    # Action選項都是在頁面上方顯示
    actions_on_top = True
    # Action選項都是在頁面下方顯示
    actions_on_bottom = False
    # 是否顯示選擇個數
    actions_selection_counter = True

添加防火牆管理模塊

{% extends "admin/base_site.html" %}
{% load i18n static %}
{% block content %}
    <link rel="stylesheet" href="https://www.blib.cn/cdn/bootstrap3.css" />
    <script src="https://www.blib.cn/cdn/jquery.js"></script>

    <style>
    #content {
    padding: 10px 10px;
    }
    .panel-body {
    padding: 10px;
    }
    </style>
    <div class="panel panel-default">
        <div class="panel-heading">
            <h3 class="panel-title">防火牆配置模塊</h3>
        </div>
    <div class="panel-body">
         <div class="panel panel-default">
                <div class="panel-body">
                    <div class="firewall-port-box">
                        <input type="text" class="bt-input-text mr5" style="width: 200px;" id="SourceAddr" placeholder="源地址">
                        <input type="text" class="bt-input-text mr5" id="Remarks" placeholder="備注/說明">
                        <select id="firewalldType" class="bt-input-text c5 mr5" name="type" style="width:80px;">
                            <option value="accept">放行IP</option>
                            <option value="drop">屏蔽IP</option>
                        </select>
                        <button id="toAccept" class="btn btn-default btn-sm" type="button">提交更改</button>
					</div>
                </div>
            </div>

    <div class="panel panel-default">
        <div class="panel-body">
            <table class="table table-hover">
                <thead>
                    <tr>
                        <th>編號</th>
                        <th>IP地址</th>
                        <th>動作</th>
                        <th>添加時間</th>
                        <th>備注</th>
                        <th>操作</th>
                    </tr>
                </thead>
                <tbody>
                    {% for item in data %}
                        <tr>
                        <td> {{ item.id }}</td>
                        <td> {{ item.SourceAddr }}</td>
                        <td> {{ item.Action }}</td>
                        <td> {{ item.DataTime }}</td>
                        <td> {{ item.Remarks }}</td>
                        <td><a href="index.html">刪除</a></td>
                        </tr>
                    {% endfor %}
                </tbody>
            </table>
        </div>
    </div>
   </div>
</div>
    <script>
    $(document).ready(function(){
        $("#toAccept").click(function(){
            var message = {"type":null,"SourceAddr":null,"Remarks":null};
            message['type'] = $("#firewalldType option:selected").val();
            message['SourceAddr'] = $("#SourceAddr").val();
            message['Remarks'] = $("#Remarks").val();
            data = JSON.stringify(message);
            $.ajax({
                url:"/echo/",
                type:"POST",
                dataType:"json",
                data:data,
                success:function () {
                    window.location.reload();
                }
            });
        });
    });
    </script>
{% endblock %}
from django.shortcuts import render,HttpResponse
from MyWeb import models
import paramiko,time,json

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

def ssh_shell(address,username,password,port,command):
    try:
        ssh.connect(address,port=port,username=username,password=password,timeout=1)
        stdin, stdout, stderr = ssh.exec_command(command)
        result = stdout.read()
        if not result:
            result=stderr.read()
        ssh.close()
        return result.decode()
    except Exception:
        return 0
    
def echo(request):
    if request.method == "GET":
        obj = models.FireWallDB.objects.all()
        print(obj)
        return render(request,"index.html",{"data":obj})
    else:
        recv = json.loads(request.body.decode("utf-8"))
        addr = recv.get("SourceAddr")
        remak = recv.get("Remarks")

        if recv.get("type") == "accept":
            cmd = 'firewall-cmd --add-rich-rule \'rule family=ipv4 source address="{}" accept\''.format(addr)
            count = models.FireWallDB.objects.filter(SourceAddr=addr).count()
            if count <2:
                retn = ssh_shell("192.168.1.20","root","123","22",cmd)
                if retn !=0:
                        obj = models.FireWallDB()
                        obj.SourceAddr = addr
                        obj.Action = "放行"
                        obj.DataTime = str(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))
                        obj.Remarks = remak
                        obj.SourceCMD = cmd
                        obj.save()
                        print("ok")
            elif recv.get("type") == "drop":
                cmd = 'firewall-cmd --add-rich-rule \'rule family=ipv4 source address="{}" drop\''.format(addr)
                print(cmd)
        else:
            print("最多兩個")
        return HttpResponse("ok")
    return render(request,"index.html")
from django.db import models

class FireWallDB(models.Model):
    id = models.AutoField(primary_key=True)
    SourceAddr = models.CharField(max_length=64)
    Action = models.CharField(max_length=64)
    DataTime = models.CharField(max_length=64)
    Remarks = models.CharField(max_length=64)
    SourceCMD = models.CharField(max_length=512)


簡單的Admin定制: 簡單的過濾器使用技巧.

# name: settings.py
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'

# name: apps.py
from django.apps import AppConfig
class MywebConfig(AppConfig):
    name = 'MyWeb'
    verbose_name = "服務器集群"

# name: 最后別忘了建庫建表
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser
# name: models.py
from django.db import models
from django.utils.html import format_html

STATUS_CHOICES = (('d', '正常'),('p', '警告'),('w', '損壞'),)

class HostInfo(models.Model):
    id = models.AutoField(primary_key=True)
    HostName = models.CharField(max_length=64,verbose_name="主機名")
    HostAddr = models.CharField(max_length=64,verbose_name="主機IP")
    DataTime = models.DateField(max_length=64,verbose_name="統計時間")
    HostStats = models.CharField(max_length=1,choices=STATUS_CHOICES,verbose_name="狀態")

    def __str__(self):
        return self.HostName
    # 用於給本表指定別名,這樣前端就不是英文的了
    class Meta():
        verbose_name = "Web前台集群"
        verbose_name_plural= "Web前台集群"
    # 自定義方法,主要負責給主機標注顏色
    def Status(self):
        if self.HostStats == 'd':
            format_td = format_html('<span style="padding:2px;background-color:green;color:white">正常</span>')
        elif self.HostStats == 'p':
            format_td = format_html('<span style="padding:2px;background-color:yellow;color:black">警告</span>')
        elif self.HostStats == 'w':
            format_td = format_html('<span style="padding:2px;background-color:red;color:white">損壞</span>')
        return format_td
    Status.short_description = "狀態"
# name: admin.py
from django.contrib import admin
from MyWeb.models import *

# 必須繼承ModelAdmin基類,才可以調整參數,HostDB則是你的表的名稱
@admin.register(HostInfo)
class MyAdmin(admin.ModelAdmin):
    admin.site.site_title="自動化后台管理"
    admin.site.site_header = "Django 管理平台"
    # list_display = 你需要或者想要展示在頁面中的字段
    list_display = ("HostName","HostAddr","DataTime","Status")
    # search_fields = 添加搜索功能,並以HostName,HostAddr作為搜索條件
    search_fields = ("HostName","HostAddr",)
    # ordering = 設置以id號作為排序條件
    ordering = ("id",)
    # list_per_page = 設置每頁顯示數據條數
    list_per_page = 10
    # list_filter = 設置一個過濾器,此處是以hostname作為過濾條件
    list_filter = ("HostName",)
    #list_editable = 設置默認可編輯字段
    list_editable = ("DataTime",)
    # date_hierarchy = 顯示詳細時間分層篩選
    date_hierarchy = 'DataTime'
    # readonly_fields = 可以設置只讀字段,就是無法修改的字段
    readonly_fields = ("HostAddr",)
    # list_display_links 指定點擊HostAddr進入編輯狀態
    list_display_links = ("HostAddr",)



添加已過期標志: 通過取出當前時間與數據庫中現有時間對比,來實現是否過期.

# name: admin.py
from django.contrib import admin
from MyWeb.models import *
@admin.register(HostDB)
class MyAdmin(admin.ModelAdmin):
    list_display = ("id","date","Status")

# name: models.py
from django.db import models
from django.utils.html import format_html
import datetime

class HostDB(models.Model):
    id = models.AutoField(primary_key=True)
    date = models.CharField(max_length=64)
    def Status(self):
        NowData = datetime.date.today()
        if self.date >= str(NowData):
            ret = "未過期"
            color = "green"
            return format_html('<span style="color:{};">{}</span>',color,ret,)
        else:
            ret = "已過期"
            color = "red"
            return format_html('<span style="color:{};">{}</span>', color, ret,)
    Status.short_description = "是否過期"

添加進度條展示: HTML5默認支持進度條標簽,使用progress我們直接使用這個標簽就好了.

# name: admin.py
from django.contrib import admin
from MyWeb.models import *

@admin.register(HostDB)
class MyAdmin(admin.ModelAdmin):
    list_display = ("id","Count","Speed")

# name: models.py
from django.db import models
from django.utils.html import format_html

class HostDB(models.Model):
    id = models.AutoField(primary_key=True)
    Count = models.IntegerField()

    def Speed(self):
        return format_html('<progress max="100" value="{}"></progress>',self.Count)
    Speed.short_description = "當前進度"

增加自定義actions: 自定義Action標簽,Action標簽就是Admin頁面中左上角的橫線部分,我們自己增加新的.

# name: admin.py
from django.contrib import admin
from MyWeb.models import *

# 必須繼承ModelAdmin基類,才可以調整參數,HostDB則是你的表的名稱
@admin.register(HostInfo)
class MyAdmin(admin.ModelAdmin):
    admin.site.site_title="自動化后台管理"
    admin.site.site_header = "Django 管理平台"
    <省略部分...>
    def func(self,request,queryset):
        # 此處可以寫一些執行動作
        print(self,request,queryset)
    func.short_description = "自定義active動作"
    actions = [func,]
    # Action選項都是在頁面上方顯示
    actions_on_top = True
    # Action選項都是在頁面下方顯示
    actions_on_bottom = False
    # 是否顯示選擇個數
    actions_selection_counter = True


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM