利用Django和自帶的Admin后臺快速開發手機管理系統

項目背景

公司內部測試使用的手機歷史不是很多,沒有專門納管。后面隨著規模變大,測試手機也越來越多,測試、開發、設計等人員都會借用。時間長了不確定手機都在誰的手里,不方便管理。

測試提出需求,需要有個簡單的小系統能進行手機統一管理。

需求有

1、管理員可以進行手機錄入、修改、刪除、查詢等功能。

2、除了手機管理里面,測試、開發、設計等人員可以查看手機列表手機借用列表 以及申請手機 三個核心功能

3、測試、開發、設計等人員申請手機之后,自動發送消息(郵件)給管理員。然后找管理員認領手機

4、手機使用完畢歸還時,先交還手機給 管理員,然后管理員修改 ”手機借用列表“ 中的對應記錄的 ”歸還時間“

設計思路

1、定義 Phone 和 BorrowRecord 兩個模型

2、利用Django自帶的后臺快速實現

3、在Django后臺自定義action,進行”手機申請“

4、申請按鈕點擊之后,同步給管理員發送消息(郵箱、釘釘)

進入開發

1、模型定義

這里除了手機序列號,還添加了 手機品牌和手機型號兩個屬性,便于后續擴展。

另外時間上設計了 采購時間、入庫時間和報廢時間三個屬性。

手機的狀態有 空閑中、被借走、已故障三種,當然你可以結合自己實際的情況設置其他狀態。

# cmdb/models/phone.py
from django.db import models
from django.contrib.auth import get_user_model


User = get_user_model()


class Phone(models.Model):
    STATUS = (
        ('空閑中', '空閑中'),
        ('被借走', '被借走'),
        ('已故障', '已故障')
    )
    brand = models.CharField(max_length=32, unique=True, verbose_name='手機品牌')
    model = models.CharField(max_length=32, verbose_name='手機型號')
    serial_number = models.CharField(max_length=64, unique=True, verbose_name='手機序列號')
    create_time = models.DateTimeField(auto_now=True, verbose_name='入庫時間')
    buy_time = models.DateField(null=True, blank=True, verbose_name='采購時間')
    fault_time = models.DateField(null=True, blank=True, verbose_name='故障時間')
    status = models.CharField(max_length=12, choices=STATUS, default='空閑中', verbose_name='手機狀態')

    def __str__(self) -> str:
        return f'{self.model}/{self.serial_number}'
    
    class Meta:
        verbose_name = '測試手機管理'
        verbose_name_plural = verbose_name


class BorrowRecord(models.Model):
    user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='手機借用人')
    phone = models.ForeignKey(Phone, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='借用的手機')
    borrow_date = models.DateTimeField(auto_now_add=True, verbose_name='借用時間')
    return_date = models.DateTimeField(null=True, blank=True, verbose_name='歸還時間')

    def __str__(self) -> str:
        return f'{self.user.get_username}/{self.phone.model}'
    
    class Meta:
        verbose_name = '手機借用/歸還記錄'
        verbose_name_plural = verbose_name

2、進行配置和綁定應用

# 配置可訪問主機IP
ALLOWED_HOSTS = ['127.0.0.1']

# 綁定應用到項目
INSTALLED_APPS = [
    ... ...
    'cmdb'
]

# 設置 templates 根目錄
# 默認會從 appname/templates/appname 目錄尋找 ('APP_DIRS': True 參數決定)
TEMPLATES = [
    ... ...
    'DIRS': [os.path.join(BASE_DIR, 'templates')],
    ... ...
]

這里是項目演示,所以數據庫使用默認的 Sqlite 數據庫即可

3、后臺的自定義

因為是借助于Django自帶后臺快速開發一個簡易版手機管理系統,所有手機的管理和用戶的借用都是在 Django默認后臺實現的。

默認創建模型之后,在應用的 admin.py中進行綁定,然后就可以通過 自帶的后臺進行模型的管理,比如這里的 手機和手機借用記錄的管理。

但是默認是沒有”申請借用“的功能的,這個就需要我們開發對應的功能,并且添加到Django Admin后臺去。

核心知識: 通過繼承admin.ModelAdmin來實現自定義 模型的ModelAdmin 行為 (展示、搜索、排序、方法等)

這里先給出代碼,然后進行代碼分析

# cmdb/admin.py
from django.contrib import admin, messages
from cmdb.models import BorrowRecord, Phone
from django.http import HttpResponseRedirect
from django.urls import reverse


class PhoneAdmin(admin.ModelAdmin):
    list_display = ('brand', 'model', 'serial_number', 'fault_time', 'create_time', 'status', 'fault_time')
    list_filter = ('brand', 'status')
    search_fields = ('status', 'model', 'serial_number')
    actions = ['apply_for_borrow']
    def apply_for_borrow(self, request, queryset):
        if len(queryset) > 1:
            self.message_user(request, '抱歉,每次只能申請一臺手機', level=messages.ERROR)
        else:
            if queryset[0].status != '空閑中':
                self.message_user(request, '抱歉,不能選擇已故障或者被借走的手機', level=messages.ERROR)
            else:
                obj = queryset[0]
                next_url = '/admin/cmdb/phone/'
                base_url = reverse('cmdb:borrow-phone', kwargs={'pk': obj.id})
                borrow_url = f'{base_url}?next={next_url}'
                return HttpResponseRedirect(borrow_url)
    apply_for_borrow.short_description = '申請借用'


class BorrowRecordAdmin(admin.ModelAdmin):
    list_display = ('phone', 'user', 'borrow_date', 'return_date')
        
# Register your models here.
admin.site.register(Phone, PhoneAdmin)
admin.site.register(BorrowRecord, BorrowRecordAdmin)

上面定義了 PhoneAdmin 和 BorrowRecordAdmin 兩個ModelAdmin類,然后通過 admin.site.register 把 ModelAdmin 類綁定到 模型上,注冊到Django的后臺去。

其中

  • list_display
  • list_filter
  • search_fields
  • actions 存放自定義的”操作性方法“,比如我們需要的 ”申請借用“ 的功能

這里在 PhoneAdmin 中定義方法 apply_for_borrow, 在這個方法中我們進行”申請借用“ 資源的限制 (因為是從后臺選擇定義然后進行處理)

3.1、每次只能選擇一個手機 len(queryset) 只能等于1

3.2、選擇的手機狀態只能是 ”空閑中“ 的

3.3、選擇 ”一個空閑中“的手機之后,跳轉到 ”借用“邏輯處理的view視圖,進行實際的借用邏輯處理。

3.4、這里做了個特殊的處理,就是借用邏輯處理完畢之后,再跳回到當前后臺的手機記錄頁面。

4、借用邏輯開發

這里先給出完整代碼,然后進行分析說明

# cmdb/views.py
from django.shortcuts import render, HttpResponse, redirect
from django.contrib.auth.decorators import login_required
from cmdb.models import Phone, BorrowRecord
from django.utils import timezone
from django.http import HttpResponseRedirect
from django.contrib import messages


@login_required
def borrow_phone(request, pk):
    """
    申請借用手機視圖
    """
    phone = Phone.objects.get(pk=pk)
    pr = BorrowRecord()
    pr.user = request.user
    pr.borrow_date = timezone.now()
    pr.phone = phone
    pr.save()
    
    phone.status = '被借走'
    phone.save()
    
    messages.success(request, '手機借用成功')
    return redirect(request.GET.get('next', 'admin:index'))

4.1、這里先獲取到待借用的手機 (phone = Phone.objects.get(pk=pk))

4.2、然后新增借用記錄 15到19行,其中配置了借用人(request.user)、借用時間 (timezone.now() 當期時間)已經借用的手機,就是第14行獲取到的手機。

4.3、同時記得修改手機的狀態,從 “空閑中“ 修改為 "被借走"

4.4、這里額外使用的 Django的message機制,通過它可以在Django后臺進行頁面消息提示 (第24行)

4.5、最后根據獲取到的next 跳轉回到之前的頁面。

5、消息通知開發

這是主要是通過發送郵件,讓管理員知道“誰在借用手機,借用的是哪個手機”,好提前做準備。

具體功能也是通過Django的 send_mail 函數來實現。

5.1、settings配置

# proj/settings.py
# 配置郵件信息
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.qiye.163.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = 'ops@colinspace.com'
EMAIL_HOST_PASSWORD = 'xxxxxxxx'
DEFAULT_FROM_EMAIL = 'ops@colinspace.com'
# 管理員郵箱
ADMIN_EMAIL = 'admin@colinspace.com'

5.2、views中借用邏輯修改

# cmdb/views.pu
@login_required
def borrow_phone(request, pk):
    """
    申請借用手機視圖
    """
    ... ...

    # 發送郵件邏輯
    subject = f'[{request.user}] 申請借用手機'
    message = f'[{request.user}] 申請借用手機 ({phone.brand} - {phone.model} - {phone.serial_number})'
    recipient_list = [settings.ADMIN_EMAIL]
    send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, recipient_list)
    
    messages.success(request, '手機借用成功')
    return redirect(request.GET.get('next', 'admin:index'))

然后普通用戶在后臺申請借用手機之后,管理員就會收到如下的郵件信息

image.png

6、權限管控配置

主要是在Django Admin后臺新增用戶的時候,配置相關權限(User permissions) 如下圖所示

image.png

只給 兩個視圖的view(查看)權限即可。

在ModelAdmin類中定義的方法,是沒有做權限限制的

每個人都可以使用申請借用的功能

下圖所示是普通用戶James登錄看到的效果,他只有 兩個視圖的view的權限

看到左側沒有”?“ 不能新增模型記錄,然后在列表的action中,只有 ”申請借用“ 選項,而沒有默認的 ”Deleted select 測試手機管理“ 選項。

image.png

通過如上的開發和配置,我們就實現測試提出的 手機管理系統的基本需求。

然后給服務配置域名,就可以交付給測試組進行使用了。是不是很快就上手了一個小系統呢~

系統的詳細代碼詳見 https://gitee.com/colin5063/django-examples/tree/main/django_phone_management (復制到瀏覽器再打開哦)

克隆到本地之后,按照 django_phone_management/ReadMe.md 提示進行操作即可運行項目。

有問題及時反饋哦~

如果你覺得有所收獲,歡迎關注公眾號"菩提老鷹"進行點贊和喜歡哦~

一起交流,分享知識,快樂生活,我是老鷹,我們下一期見~

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,345評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,494評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,283評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,953評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,714評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,410評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,940評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,776評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,210評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,654評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,958評論 2 373

推薦閱讀更多精彩內容