開源的HAdmin項目

HAdmin后端對DRF封裝

我想實現(xiàn)一個這樣的理想國:

比xadmin漂亮;比xadmin強大胃碾;前后端分離;基于Django和DRF涂屁;智能化配置书在。

以上幾點,是我們對HAdmin的設(shè)想拆又,設(shè)想這樣的后端能夠相對自動化輸出接口儒旬,讓前端能夠根據(jù)配置文件認識輸出的標準數(shù)據(jù)結(jié)構(gòu),從而進行渲染帖族。

于是栈源,初步版本的HAdmin上線了。

快速開始

安裝

pip install hadmin

使用方式

from rest_framework import viewsets
from hadmin import mixins

class CustomConfigViewSet(mixins.PageConfigMixin, viewsets.GenericViewSet):
    list_class = CustomListSerializer
    filter_class = CustomFilter
    create_class = CustomCreateSerializer
    read_class = CustomReadSerializer
    extra = {}

其實竖般,就是用HAdmin下的mixins替代rest_framework下的mixins

并且甚垦,增加了一個PageConfigMixin方法,這個方法包含了四種配置文件的輸出方式涣雕,分別是:

list_class 列表的配置信息

filter_class 篩選器的配置信息

create_class 創(chuàng)建數(shù)據(jù)表單的配置信息

read_class 讀取最終數(shù)據(jù)的配置信息

extra 是額外擴展的數(shù)據(jù)艰亮,可以是字典或者列表等任意可以轉(zhuǎn)換成json的值,會原樣遞送到前端挣郭,用于前端渲染特殊情況下使用迄埃,非必填,根據(jù)需要使用

每個對應(yīng)的都是序列化器的的類兑障,序列化器建議每個方法用不同類侄非,這樣可以自由定義。

每個序列化器類的元數(shù)據(jù)可以增加一個custom字典流译,以便進行解析逞怨。

輸出到前端的數(shù)據(jù)樣例:

{
    "filter": {
        "base": [
            {
                "label": "手機號", 
                "method": "input", 
                "default": "", 
                "url": "", 
                "limit": 1, 
                "span": 6, 
                "key": "mobile"
            }, 
            {
                "label": "姓名", 
                "method": "input", 
                "default": "", 
                "url": "", 
                "limit": 1, 
                "span": 6, 
                "key": "name"
            }, 
            {
                "label": "姓名", 
                "method": "input", 
                "default": "", 
                "url": "", 
                "limit": 1, 
                "span": 6, 
                "key": "desc"
            }, 
            {
                "label": "新房客源", 
                "method": "select", 
                "default": "", 
                "url": "", 
                "limit": 1, 
                "span": 6, 
                "key": "new", 
                "options": [
                    {
                        "id": "-1000", 
                        "title": "不限"
                    }, 
                    {
                        "id": "true", 
                        "title": "是"
                    }, 
                    {
                        "id": "false", 
                        "title": "否"
                    }, 
                    {
                        "id": "isnull", 
                        "title": "未填寫"
                    }
                ]
            }, 
            {
                "label": "二手房客源", 
                "method": "select", 
                "default": "", 
                "url": "", 
                "limit": 1, 
                "span": 6, 
                "key": "old", 
                "options": [
                    {
                        "id": "-1000", 
                        "title": "不限"
                    }, 
                    {
                        "id": "true", 
                        "title": "是"
                    }, 
                    {
                        "id": "false", 
                        "title": "否"
                    }, 
                    {
                        "id": "isnull", 
                        "title": "未填寫"
                    }
                ]
            }, 
            {
                "label": "租房客源", 
                "method": "select", 
                "default": "", 
                "url": "", 
                "limit": 1, 
                "span": 6, 
                "key": "rent", 
                "options": [
                    {
                        "id": "-1000", 
                        "title": "不限"
                    }, 
                    {
                        "id": "true", 
                        "title": "是"
                    }, 
                    {
                        "id": "false", 
                        "title": "否"
                    }, 
                    {
                        "id": "isnull", 
                        "title": "未填寫"
                    }
                ]
            }
        ], 
        "adv": [ ], 
        "height": 100, 
        "fields": {
            "mobile": "", 
            "name": "", 
            "desc": "", 
            "new": "", 
            "old": "", 
            "rent": ""
        }
    }, 
    "create": {
        "fields": {
            "master": null, 
            "region": null, 
            "admins": [ ], 
            "mobile": "", 
            "name": "", 
            "new": false, 
            "old": false, 
            "rent": false, 
            "desc": ""
        }, 
        "detail": [
            {
                "label": "主理人", 
                "help_text": null, 
                "field_name": "master", 
                "required": true, 
                "type": "PrimaryKeyRelatedField", 
                "choices": [
                    {
                        "id": "1", 
                        "title": "hofeng"
                    }, 
                    {
                        "id": "13", 
                        "title": "18961330033"
                    }, 
                    {
                        "id": "83", 
                        "title": "shanghai001"
                    }, 
                    {
                        "id": "84", 
                        "title": "shanghai002"
                    }, 
                    {
                        "id": "85", 
                        "title": "shanghai003"
                    }, 
                    {
                        "id": "86", 
                        "title": "suqian001"
                    }
                ]
            }, 
            {
                "label": "地區(qū)", 
                "help_text": null, 
                "field_name": "region", 
                "required": true, 
                "type": "PrimaryKeyRelatedField", 
                "choices": [
                    {
                        "id": "1", 
                        "title": "上海【310000】"
                    }, 
                    {
                        "id": "21", 
                        "title": "宿遷【321300】"
                    }, 
                    {
                        "id": "34", 
                        "title": "鹽城【320900】"
                    }
                ]
            }, 
            {
                "label": "協(xié)作人", 
                "help_text": null, 
                "field_name": "admins", 
                "required": true, 
                "type": "ManyRelatedField", 
                "choices": [
                    {
                        "id": "1", 
                        "title": "hofeng"
                    }, 
                    {
                        "id": "13", 
                        "title": "18961330033"
                    }, 
                    {
                        "id": "83", 
                        "title": "shanghai001"
                    }, 
                    {
                        "id": "84", 
                        "title": "shanghai002"
                    }, 
                    {
                        "id": "85", 
                        "title": "shanghai003"
                    }, 
                    {
                        "id": "86", 
                        "title": "suqian001"
                    }
                ]
            }, 
            {
                "label": "手機號", 
                "help_text": "客源手機號", 
                "field_name": "mobile", 
                "required": true, 
                "type": "CharField"
            }, 
            {
                "label": "姓名", 
                "help_text": null, 
                "field_name": "name", 
                "required": false, 
                "type": "CharField"
            }, 
            {
                "label": "新房客源", 
                "help_text": null, 
                "field_name": "new", 
                "required": false, 
                "type": "BooleanField"
            }, 
            {
                "label": "二手房客源", 
                "help_text": null, 
                "field_name": "old", 
                "required": false, 
                "type": "BooleanField"
            }, 
            {
                "label": "租房客源", 
                "help_text": null, 
                "field_name": "rent", 
                "required": false, 
                "type": "BooleanField"
            }, 
            {
                "label": "簡要說明", 
                "help_text": null, 
                "field_name": "desc", 
                "required": false, 
                "type": "CharField", 
                "base_template": "textarea.html"
            }
        ]
    }, 
    "list": [
        {
            "label": "ID", 
            "field_name": "id", 
            "type": "IntegerField", 
            "width": "80"
        }, 
        {
            "label": "手機號", 
            "field_name": "mobile", 
            "type": "CharField"
        }, 
        {
            "label": "姓名", 
            "field_name": "name", 
            "type": "CharField"
        }, 
        {
            "label": "主理人", 
            "field_name": "master", 
            "type": "StringRelatedField"
        }, 
        {
            "label": "新房客源", 
            "field_name": "new", 
            "type": "BooleanField"
        }, 
        {
            "label": "二手房客源", 
            "field_name": "old", 
            "type": "BooleanField"
        }, 
        {
            "label": "租房客源", 
            "field_name": "rent", 
            "type": "BooleanField"
        }, 
        {
            "label": "添加時間", 
            "field_name": "add_time", 
            "type": "DateTimeField"
        }
    ], 
    "read": [
        {
            "label": "主理人", 
            "field_name": "master", 
            "type": "StringRelatedField"
        }, 
        {
            "label": "地區(qū)", 
            "field_name": "region", 
            "type": "StringRelatedField"
        }, 
        {
            "label": "協(xié)作人", 
            "field_name": "admins", 
            "type": "ManyRelatedField"
        }, 
        {
            "label": "添加時間", 
            "field_name": "add_time", 
            "type": "DateTimeField"
        }, 
        {
            "label": "手機號", 
            "field_name": "mobile", 
            "type": "CharField"
        }, 
        {
            "label": "姓名", 
            "field_name": "name", 
            "type": "CharField"
        }, 
        {
            "label": "新房客源", 
            "field_name": "new", 
            "type": "BooleanField"
        }, 
        {
            "label": "二手房客源", 
            "field_name": "old", 
            "type": "BooleanField"
        }, 
        {
            "label": "租房客源", 
            "field_name": "rent", 
            "type": "BooleanField"
        }, 
        {
            "label": "簡要說明", 
            "field_name": "desc", 
            "type": "CharField"
        }
    ]
}

下面是具體的使用方法

list_class

class CustomListSerializer(serializers.ModelSerializer):
    master = serializers.StringRelatedField()
    add_time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S')

    class Meta:
        model = Custom
        fields = ["id", "mobile", "name", "master", "new", "old", "rent", "add_time"]
        custom = {
            "id": {'width': '80'}
        }

這是一個典型的列表讀取的序列化器福澡,元數(shù)據(jù)中規(guī)定的輸出字段叠赦,新增的custom字典表明某個字段的特別約定。

字典的健名用字段名表示定義某個字段革砸;

value值是一個字典除秀,健名自己定義窥翩,反饋到前端后,前端方便進行解析鳞仙。

建議保留width,label這類字段笔时,總之棍好,這里定義什么,前端就會收到什么允耿,然后前端進行渲染借笙。

輸出到前端后,對應(yīng)參數(shù)健名為:list

filter_class

作為篩選器较锡,要定義每個篩選項业稼,這是沒辦法避免的,例如:

class CustomFilter(django_filters.rest_framework.FilterSet):
    mobile = django_filters.CharFilter(method='keyword_filter', help_text="手機號")
    name = django_filters.CharFilter(method='keyword_filter', help_text="姓名")
    desc = django_filters.CharFilter(method='keyword_filter', help_text="說明")
    new = django_filters.BooleanFilter(method='common_filter', help_text="新房客源", label={'options': get_easy_bool()})
    old = django_filters.BooleanFilter(method='common_filter', help_text="二手房客源", label={'options': get_easy_bool()})
    rent = django_filters.BooleanFilter(method='common_filter', help_text="租房客源", label={'options': get_easy_bool()})

以上就是對篩選器的定義蚂蕴,對項的定義低散,放在label進行定義,選擇類的給options值骡楼,help_text是顯示出來的名稱

輸出到前端后熔号,對應(yīng)參數(shù)健名為:filter

create_class

創(chuàng)建類的輸出,是為了前端自動構(gòu)造提交表單而定鸟整,序列化器寫法沒有特別引镊,和list一樣,可以在元數(shù)據(jù)中增加一個custom字典篮条,對應(yīng)把每個字段的特別要求輸送到前端弟头。

和其他不同的是,create的Meta下可以額外增加一個tabs涉茧,結(jié)構(gòu)為:

tabs = [{
            'label': '基本信息',
            'fields': ['mobile', 'name', 'region', 'desc']
        }, {
            'label': '權(quán)限配置',
            'fields': ['master', 'admins', 'new', 'old', 'rent']
        }]

這樣設(shè)定赴恨,前端就可以得到這個tabs,可以用于添加表單分步執(zhí)行降瞳。

輸出到前端后嘱支,對應(yīng)參數(shù)健名為:create

read_class

讀取詳細內(nèi)容的序列化器,要注意的是最好不要構(gòu)建外鍵對象挣饥,而是要用serializers.StringRelatedField()方法把外鍵進行文本化除师,這樣才能在前端正常顯示。

輸出到前端后扔枫,對應(yīng)參數(shù)健名為:read

extra

這個用于額外給前端一個擴展的數(shù)據(jù)字段汛聚,可以設(shè)定一切能夠轉(zhuǎn)為json的數(shù)據(jù),用于自己定義與前端的協(xié)議

輸入到前端后短荐,對應(yīng)參數(shù)健名為:extra

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末倚舀,一起剝皮案震驚了整個濱河市叹哭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌痕貌,老刑警劉巖风罩,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異舵稠,居然都是意外死亡超升,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門哺徊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來室琢,“玉大人,你說我怎么就攤上這事落追∮危” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵轿钠,是天一觀的道長巢钓。 經(jīng)常有香客問我,道長疗垛,這世上最難降的妖魔是什么竿报? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮继谚,結(jié)果婚禮上烈菌,老公的妹妹穿的比我還像新娘。我一直安慰自己花履,他們只是感情好芽世,可當我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著诡壁,像睡著了一般济瓢。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上妹卿,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天旺矾,我揣著相機與錄音,去河邊找鬼夺克。 笑死箕宙,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的铺纽。 我是一名探鬼主播柬帕,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了陷寝?” 一聲冷哼從身側(cè)響起锅很,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎凤跑,沒想到半個月后爆安,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體仔引,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡肤寝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年鲤看,在試婚紗的時候發(fā)現(xiàn)自己被綠了耍群。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡慷吊,死狀恐怖溉瓶,靈堂內(nèi)的尸體忽然破棺而出谤民,到底是詐尸還是另有隱情,我是刑警寧澤触创,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布哼绑,位于F島的核電站碉咆,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏帽蝶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一佃乘、第九天 我趴在偏房一處隱蔽的房頂上張望驹尼。 院中可真熱鬧,春花似錦新翎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蔚鸥。三九已至,卻和暖如春馆类,著一層夾襖步出監(jiān)牢的瞬間乾巧,已是汗流浹背预愤。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工鳖粟, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留向图,地道東北人泳秀。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓嗜傅,卻偏偏與公主長得像,于是被迫代替她去往敵國和親檩赢。 傳聞我的和親對象是個殘疾皇子吕嘀,可洞房花燭夜當晚...
    茶點故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容