xadmin的進(jìn)階開(kāi)發(fā)
因版本問(wèn)題.有些配置可能無(wú)效
自定義icon
xadmin的圖標(biāo)采用的是第三方css樣式font awesome
,我們可以進(jìn)官網(wǎng)下載最新的樣式替代原本的晨仑,下載地址:http://www.fontawesome.com.cn/
下載完后把里面的“css”和“fonts”兩個(gè)文件夾拷貝到xadmin的源碼(路徑:xadmin/static/vendor/font-awesome
)里面
使用model_icon
來(lái)進(jìn)行修改
# Course的admin管理器
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'
默認(rèn)排序呻畸、只讀字段和不顯示的字段
課程:
- 按點(diǎn)擊數(shù)倒序排序
- 點(diǎn)擊數(shù)不能編輯
- 不顯示收藏人數(shù)
# Course的admin管理器
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'] #過(guò)濾
model_icon = 'fa fa-book' #圖標(biāo)
ordering = ['-click_nums'] #排序
readonly_fields = ['click_nums'] #只讀字段,不能編輯
exclude = ['fav_nums'] #不顯示的字段
下拉框搜索
寫(xiě)在外鍵所指的adminx配置中
relfield_style = 'fk-ajax'
當(dāng)有外鍵指向他巴柿,會(huì)以ajax方式加載
數(shù)據(jù)量過(guò)大時(shí)很有用
inlines添加數(shù)據(jù)
目前在添加課程的時(shí)候沒(méi)法添加章節(jié)和課程資源雌贱,我們可以用inlines去實(shí)現(xiàn)這一功能
class LessonInline(object):
model = Lesson
extra = 0
class CourseResourceInline(object):
model = CourseResource
extra = 0
# 在CourseAdmin中使用inlines添加上面兩個(gè)的方法
class CourseAdmin(object):
inlines = [LessonInline,CourseResourceInline] #增加章節(jié)和課程資源
一張表分兩個(gè)Model來(lái)管理
課程里面分為輪播課程和不是輪播課程兩種類型啊送,我們可以分開(kāi)來(lái)管理
在course/models.py
里面新建一個(gè)Model
class BannerCourse(Course):
'''顯示輪播課程'''
class Meta:
verbose_name = '輪播課程'
verbose_name_plural = verbose_name
#這里必須設(shè)置proxy=True,這樣就不會(huì)再生成一張表欣孤,同時(shí)還具有Model的功能
proxy = True
course/adminx.py
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'] #過(guò)濾
model_icon = 'fa fa-book' #圖標(biāo)
ordering = ['-click_nums'] #排序
readonly_fields = ['click_nums'] #只讀字段
exclude = ['fav_nums'] #不顯示的字段
inlines = [LessonInline,CourseResourceInline] #增加章節(jié)和課程資源
def queryset(self):
# 重載queryset方法馋没,來(lái)過(guò)濾出我們想要的數(shù)據(jù)的
qs = super(CourseAdmin, self).queryset()
# 只顯示is_banner=True的課程
qs = qs.filter(is_banner=False)
return qs
class BannerCourseAdmin(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]
def queryset(self):
#重載queryset方法,來(lái)過(guò)濾出我們想要的數(shù)據(jù)的
qs = super(BannerCourseAdmin, self).queryset()
#只顯示is_banner=True的課程
qs = qs.filter(is_banner=True)
return qs
# 將管理器與model進(jìn)行注冊(cè)關(guān)聯(lián)
xadmin.site.register(Course, CourseAdmin)
xadmin.site.register(BannerCourse, BannerCourseAdmin)
xadmin的其它常見(jiàn)功能
可以在列表上快速修改內(nèi)容
list_editable = [ 'degree','desc']
自定義函數(shù)作為列
def get_zj_nums(self):
return self.lesson_set.all().count()
get_zj_nums.short_description = "章節(jié)數(shù)"
顯示自定義的html代碼
def go_to(self):
from django.utils.safestring import mark_safe
# 如果不mark safe降传。會(huì)對(duì)其進(jìn)行轉(zhuǎn)義
return mark_safe("<a )
go_to.short_description = "跳轉(zhuǎn)"
refresh定時(shí)刷新工具
refresh_times = [3,5] #自動(dòng)刷新(里面是秒數(shù))
字段聯(lián)動(dòng)
應(yīng)用場(chǎng)景:當(dāng)添加一門(mén)課程的時(shí)候篷朵,希望課程機(jī)構(gòu)里面的課程數(shù) +1
重寫(xiě)xadmin的save_models方法
def save_models(self):
# 在保存課程的時(shí)候統(tǒng)計(jì)課程機(jī)構(gòu)的課程數(shù)
# 字段聯(lián)動(dòng)
obj = self.new_obj
# 新增課程還沒(méi)有保存,統(tǒng)計(jì)的課程數(shù)少一個(gè)
obj.save()
# 必須確定存在婆排。
if obj.course_org is not None:
# obj實(shí)際是一個(gè)course對(duì)象
course_org = obj.course_org
course_org.course_nums = Course.objects.filter(course_org = course_org).count()
course_org.save()
xadmin自行探究
- local 語(yǔ)言包
- migration 數(shù)據(jù)表的記錄
- plugins 每一個(gè)后臺(tái)頁(yè)面都是一個(gè)plugin 插件機(jī)制
- static文件声旺。js css
- template xadmin自己用到的html文件
- 對(duì)django admin的封裝
增加富文本編輯器Ueditor
下載地址 https://github.com/twz915/DjangoUeditor3/
解壓后,把DjangoUeditor文件夾拷貝到項(xiàng)目目錄下面
# settings中添加app
INSTALLED_APPS = [
'DjangoUeditor',
]
# 富文本編輯器url
path('ueditor/',include('DjangoUeditor.urls' )),
course/models.py
中Course修改detail字段
class Course(models.Model):
# detail = models.TextField("課程詳情")
detail = UEditorField(verbose_name=u'課程詳情', width=600, height=300, imagePath="courses/ueditor/",
filePath="courses/ueditor/", default='')
xadmin/plugs
目錄下新建ueditor.py文件段只,代碼如下
import xadmin
from xadmin.views import BaseAdminPlugin, CreateAdminView, ModelFormAdminView, UpdateAdminView
from DjangoUeditor.models import UEditorField
from DjangoUeditor.widgets import UEditorWidget
from django.conf import settings
class XadminUEditorWidget(UEditorWidget):
def __init__(self, **kwargs):
self.ueditor_options = kwargs
self.Media.js = None
super(XadminUEditorWidget,self).__init__(kwargs)
class UeditorPlugin(BaseAdminPlugin):
def get_field_style(self, attrs, db_field, style, **kwargs):
if style == 'ueditor':
if isinstance(db_field, UEditorField):
widget = db_field.formfield().widget
param = {}
param.update(widget.ueditor_settings)
param.update(widget.attrs)
return {'widget':XadminUEditorWidget(**param)}
return attrs
def block_extrahead(self, context, nodes):
js = '<script type="text/javascript" src="%s"></script>' %(settings.STATIC_URL + "ueditor/ueditor.config.js")
js += '<script type="text/javascript" src="%s"></script>' %(settings.STATIC_URL + "ueditor/ueditor.all.min.js")
nodes.append(js)
xadmin.site.register_plugin(UeditorPlugin, UpdateAdminView)
xadmin.site.register_plugin(UeditorPlugin, CreateAdminView)
xadmin/plugs/__init__.py
里面添加ueditor插件
PLUGINS = (
'ueditor',
)
course/adminx.py
中使用
class CourseAdmin(object):
#detail就是要顯示為富文本的字段名
style_fields = {"detail": "ueditor"}
在模板中必須關(guān)閉Django的自動(dòng)轉(zhuǎn)義才能正常顯示
<div class="tab_cont tab_cont1">
{% autoescape off %}
{{ course.detail }}
{% endautoescape %}
</div>
或者
{{ course.detail|safe }}
導(dǎo)入excel
- 如何注入導(dǎo)入excel代碼到菜單
- 如何只在課程列表顯示
- 如何接收文件對(duì)文件進(jìn)行處理
新建xadmin/plugins/excel.py
import xadmin
from xadmin.views import BaseAdminPlugin, ListAdminView
from django.template import loader
#excel 導(dǎo)入
class ListImportExcelPlugin(BaseAdminPlugin):
import_excel = False
def init_request(self, *args, **kwargs):
return bool(self.import_excel)
def block_top_toolbar(self, context, nodes):
nodes.append(loader.render_to_string('xadmin/excel/model_list.top_toolbar.import.html', context=get_context_dict(context)))
xadmin.site.register_plugin(ListImportExcelPlugin, ListAdminView)
添加到init.py文件中
PLUGINS = (
'excel',
)
新建xadmin/templates/xadmin/excel/model_list.top_toolbar.import.html
{% load i18n %}
<div class="btn-group export">
<a class="dropdown-toggle btn btn-default btn-sm" data-toggle="dropdown" href="#">
<i class="icon-share"></i> 導(dǎo)入 <span class="caret"></span>
</a>
<ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
<li><a data-toggle="modal" data-target="#export-modal-import-excel"><i class="icon-circle-arrow-down"></i> 導(dǎo)入 Excel</a></li>
</ul>
<script>
function fileChange(target){
//檢測(cè)上傳文件的類型
var imgName = document.all.submit_upload.value;
var ext,idx;
if (imgName == ''){
document.all.submit_upload_b.disabled=true;
alert("請(qǐng)選擇需要上傳的 xls 文件!");
return;
} else {
idx = imgName.lastIndexOf(".");
if (idx != -1){
ext = imgName.substr(idx+1).toUpperCase();
ext = ext.toLowerCase( );
{# alert("ext="+ext);#}
if (ext != 'xls' && ext != 'xlsx'){
document.all.submit_upload_b.disabled=true;
alert("只能上傳 .xls 類型的文件!");
return;
}
} else {
document.all.submit_upload_b.disabled=true;
alert("只能上傳 .xls 類型的文件!");
return;
}
}
}
</script>
<div id="export-modal-import-excel" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<form method="post" action="" enctype="multipart/form-data">
{% csrf_token %}
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">導(dǎo)入 Excel</h4>
</div>
<div class="modal-body">
<input type="file" onchange="fileChange(this)" name="excel" id="submit_upload">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{% trans "Close" %}</button>
<button class="btn btn-success" type="submit" id="submit_upload_b"><i class="icon-share"></i> 導(dǎo)入</button>
</div>
</form>
</div><!-- /.modal-content -->
</div><!-- /.modal-dalog -->
</div><!-- /.modal -->
</div>
只需要在adminx中設(shè)置變量import_excel=True
就可以開(kāi)啟導(dǎo)入按鈕
在adminx中重寫(xiě)post
方法,將文件內(nèi)容保存到數(shù)據(jù)中
def post(self, request, *args , **kwargs):
if 'excel' in request.FILES:
pass
# 中間pass步驟不管做什么事情腮猖,都要最后return父類的
return super(CourseAdmin, self).post(request, args, kwargs)