Django快速開發實踐:Drf框架和xadmin配置指北

畫星星高手發表於2020-07-04

步驟

既然是快速開發,那廢話不多說,直接說步驟:

  • 安裝Djagno
  • 安裝Django Rest Framework
  • 定義models
  • 定義Rest framework的serializers
  • 定義Rest framework的viewsets
  • 配置Rest framework的router
  • 配置管理後臺admin
  • 根據需要寫template和對應的view

經過這些步驟就能得到一個具備完整的後端介面和後臺管理介面的網站了,如果寫了template的話還能把前端的工作也做了。

接下來按照上面提到的順序記錄一下我的開發實踐。

定義models

好像沒啥好說的,Django3多了幾個新的特性,可以用class來定義choices,這個比以前的元組定義方便一些,其他的好像沒什麼了,對了,定義ManyToMany最好設定一個related_name,方便以後在程式碼裡做反向查詢。

定義serializers

這個很簡單,只要告訴框架你需要序列化model的哪個欄位就好了。
官方文件:https://www.django-rest-framework.org/tutorial/1-serialization/

程式碼例子如下:

from .models import *
from rest_framework import serializers

class StudentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Student
        fields = ['name', 'gender', 'number', 'faculty', 'major', 'year']

附上這個Student的model程式碼:

class Student(models.Model):
    name = models.CharField('姓名', max_length=10)
    gender = models.IntegerField('性別', default=1, choices=GenderChoices)
    number = models.CharField('學號', max_length=20, blank=True)
    faculty = models.CharField('學院', max_length=20, blank=True)
    major = models.CharField('專業', max_length=20, blank=True)
    year = models.CharField('屆別', max_length=4)

    def __str__(self):
        return self.name

定義viewsets

就是把queryset和serializers關聯起來。

貼一下程式碼,對應上面的student的serializers。

from rest_framework import viewsets
from .models import *
from .serializers import *

class StudentViewSet(viewsets.ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer

配置router

可以理解為Rest Framework的urls配置。

程式碼:

from rest_framework import routers
from core import views

router = routers.DefaultRouter()
router.register('user', views.UserViewSet)

然後再加入Django的urls配置中:

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include(router.urls)),  # 這裡
    path('api-auth/', include('rest_framework.urls')),  # 和這裡
]

乾淨利索,這個router應該和urls一樣能巢狀的,不過我沒有深入學Rest Framework,所以沒有了解到,以後有需要再查一下文件。

關於drf的簡單參考文件:

配置管理後臺admin

其實這一步也可以放在前面,就是剛定義完models的時候就配置,這樣方便管理資料。

Django自帶的這個admin可以說很強大了,可以省去很多中小型網站的管理後臺開發工作,不過預設的介面是比較醜的,這個用過的人都懂,但是又想用,怎麼辦?所以要進行美化啊,以前我只知道xadmin這個庫,國人開發的,基於bootstrap3介面,重寫了整套admin程式碼,介面好看了不少,無奈有很多bug,文件又幾乎是沒有的,很多功能實現都只能去看程式碼,體驗極差,嚴重影響開發效率……(但是為了介面好看我一開始還是隻能用這個了)
關於Django配置詳情可以看劉江大大的部落格,很詳細,在我下面的第一個參考連結裡面~

介面效果大概這樣:

然後我又發現了一個新的xadmin替代品,叫simpleui,號稱vue+element ui寫的,介面也不錯,實際體驗嘛,emmm……和xadmin互有千秋。不過這貨搞了個pro版本,也就是付費版,所以開源免費版這個能用就偷著樂了,你懂的。

介面如下,還可以換主題。

有興趣請看看官方github:https://github.com/newpanjing/simpleui

安裝xadmin

現在Django-xadmin好像已經不維護了,至少在github上看到是作者去寫純前端的xadmin框架了,然後安裝起來也是一波三折,你直接在pip安裝也不行,因為那個是xadmin的0.x版本,支援的是Django1.x的,要安裝xadmin的django2分支,才能支援Django2.x,然後我一開始用上Django3,貌似這貨還和Django3有相容問題……

那到底怎麼安裝才好啊?簡單點的方法就是官方github說的:

pip install git+git://github.com/sshwsfc/xadmin.git@django2

不過這個方法我有時候可以有時候不行,好像是github被遮蔽了吧,唉,所以還有別的方法,就是安裝打包好的wheel檔案,從xadmin官方倉庫把程式碼下載下來,然後checkout到django2分支,再執行命令打包成wheel檔案,接著就可以拿去pip安裝了,有空我上傳到pypi,方便一下有需要的同學。

安裝完執行可能還會報錯:TypeError: render() got an unexpected keyword argument 'renderer',原因是整合DjangoUeditor時出錯,需要需要修改虛擬環境下的boundfield.py檔案,位置在venv/lib/python3.6/site-packages/django/forms/boundfield.py,修改內容:

89        return widget.render(
90            name=self.html_initial_name if only_initial else self.html_name,
91            value=self.value(),
92            attrs=attrs,
93            # renderer=self.form.renderer,(93行處註釋掉,就能正常執行了)
94        )

xadmin配置

xadmin的配置和Django的差不多,但是也有一點小區別,不過還好它支援Django的messages框架,simpleui好像不支援……有毒

Django admin的配置是寫在每個app下面的admin.py檔案的,xadmin得寫在adminx.py裡,然後好像也沒法像Django一樣用裝飾器註冊admin類,下面的程式碼展示了註冊admin方法:

xadmin.site.register(model類, admin類)

注意xadmin的admin類還不能像Django一樣繼承ModelAdmin類,只能繼承BaseAdminObject或乾脆不寫,我看xadmin的原始碼是繼承自object的(跟不寫一樣)

下面這個例子就很全了,各種屬性的配置。

class CourseAdmin(object):
    '''課程'''
    list_display = [ 'name','desc','detail','degree','learn_times','students']   #顯示的欄位
    search_fields = ['name', 'desc', 'detail', 'degree', 'students']             #搜尋欄位
    list_filter = [ 'name','desc','detail','degree','learn_times','students']    #過濾欄位
    model_icon = 'fa fa-book'            #自定義圖示
    ordering = ['-click_nums']           #排序功能
    readonly_fields = ['click_nums']     #只讀欄位,不能編輯
    exclude = ['fav_nums']               #不顯示的欄位
    inlines = [LessonInline,CourseResourceInline]    #增加章節和課程資源
    list_editable = ['degree','desc'] #在列表頁可以直接編輯的
    list_display = ['get_zj_nums']  #直接使用函式名作為欄位顯示
    list_display = ['go_to']  # 跳轉到上面定義的地址
    refresh_times = [3,5]           #自動重新整理(裡面是秒數)可選3或5秒

admin類的屬性詳情

  • model_icon:圖示用的是font awesome圖示,不過這個網站國內好像訪問不了,所以我們用國內版的網站替代,http://www.fontawesome.com.cn/icons-ui/
  • inlines的配置和Django的差不多,不過不能像Django一樣整合xxxinline的父類……要定義的話參考下面的程式碼:
class LessonInline(object):
    model = Lesson
    extra = 0

class CourseResourceInline(object):
    model = CourseResource
    extra = 0
  • 還有一個圖表功能,不過我覺得沒啥用,主要是x座標換成char欄位就顯示不出來了,很噁心,例子:
data_charts = {
        "user_count": {'title': u"course_num", "x-field": "addtime", "y-field": ("course_num"),
                       "order": ('addtime',)
        }
}

效果這樣:
image.png

admin類的一些方法覆蓋

為啥要覆蓋?當然是要自定義一些操作啊,比如你要儲存使用者資訊的時候驗證某些欄位,通過才給儲存,不通過就給出提示,咋搞,覆蓋父類函式呀!

程式碼例子:

class ExamineAdmin(BaseAdminObject):
    .......

    def save_models(self):
        # 獲取儲存的新物件
        obj = self.new_obj
        # 獲取原來的物件,如果是建立新物件,則org_obj為空
        org_obj = self.org_obj

        if 不滿足條件:
            self.message_user(message="不滿足xxx條件", level='error')
        else:
            return super().save_models()

大概就這樣,顯示資訊的話基本能滿足,不過就算顯示了“不滿足xxx條件”的資訊,不儲存這個model物件,也還會出來一個儲存成功資訊,xadmin似乎沒有提供api關掉,文件啥也沒寫,要解決這個問題還是自己啃xadmin程式碼吧,不然靠搜尋和文件完全就是黑箱操作……無力吐槽

參考:

寫在最後

不得不說,使用Python Django開發網站效率太高了,很方便就做出一套可以用的API+後臺管理系統,拿來應付各種課程設計、需求簡單的外包都是綽綽有餘,而且相關資料也很多,有心學習的話花點時間掌握開發商業網站專案完全不在話下!至於有人質疑Python的效能,人家Instagram的後臺就是全套Django開發的,這億級的使用者量可不是鬧著玩的,瞭解一門技術之後好好深入學習提高比整天跟風搞些花裡胡哨的有用得多了……

不過最近看了很多net core的部落格和知乎問題,我還是看好這個net core5的未來,接下來花點時間繼續學我的C#,雖然工作可能用C++比較多……(逃

歡迎交流

交流問題請在微信公眾號後臺留言,每一條資訊我都會回覆哈~

相關文章