第十一章 在線教育平臺(xadmin的進階開發(fā))

xadmin的進階開發(fā)

標(biāo)簽: django


userprofile 注冊以及django的權(quán)限管理

  • 用戶信息放入用戶欄中(針對老版本的bug)

通過將userprofile繼承與xadmin中plugin下面的UserAdmin ,并注冊userprofile,同時注銷User矾兜。

# _*_ encoding:utf-8 _*_

__author__ = 'wrj008'
__date__ = '2018/3/9 17:15'

import xadmin
from xadmin import views
from xadmin.plugins.auth import UserAdmin, User
from .models import EmailVerifyRecord, Banner

from users.models import UserProfile


class UserProfileAdmin(UserAdmin):
    pass


class BaseSetting(object):
    enable_themes = True
    use_bootswatch = True


class GloableSetting(object):
    site_title = '教育后臺管理系統(tǒng)'
    site_footer = 'xiaojinzi'
    menu_style = 'accordion'


class EmailVerifyRecordAdmin(object):
    list_display = ['code', 'email', 'send_time', 'send_type']
    search_fields = ['code', 'email', 'send_time']
    list_filter = ['code', 'email', 'send_time', 'send_type']


class BannerAdmin(object):
    list_display = ['title', 'image', 'url', 'index', 'add_time']
    search_fields = ['title', 'image', 'url', 'index']
    list_filter = ['title', 'image', 'url', 'index', 'add_time']


xadmin.site.unregister(User)
xadmin.site.register(EmailVerifyRecord, EmailVerifyRecordAdmin)
xadmin.site.register(Banner, BannerAdmin)
xadmin.site.register(UserProfile, UserProfileAdmin)
xadmin.site.register(views.BaseAdminView, BaseSetting)
xadmin.site.register(views.CommAdminView, GloableSetting)

  • 另一種方式是通過在xadmin.auth中添加
from django.contrib.auth import get_user_model
User = get_user_model()
  • 用戶的權(quán)限管理

通過對軟件進行操作损趋。

用戶后臺界面中的icon圖片進行修改

django用的是font-awesome樣式風(fēng)格。 地址

在修改的adminx的下面添加
model_icon = 'fa fa-circle-o-notch fa-spin'
排序
ordering = ['-click_nums']
只讀字段顯示
readonly_fields = ['click_nums']
不顯示字段(與上面會存在沖突)
exclude = ['']
下拉選擇過多時椅寺,通過外鍵的主表添加字段浑槽,異步搜索呈現(xiàn)內(nèi)容
relfield_style = 'fk-ajax'
列表中字段直接修改
list_editable = ['']

自定義列表返回數(shù)據(jù),同一model兩個注冊管理器

  • inline操作

添加課程的同時在課程截界面添加章節(jié)信息返帕。

class LessonAinline(object):
    model = Lesson
    extra = 0


class CourseAdmin(object):
    list_display = ['name', 'desc', 'detail', 'degree', 'learn_time', 'students', 'fav_nums', 'click_nums', 'image',
                    'add_time']
    search_fields = ['name', 'desc', 'detail', 'degree', 'learn_time', 'students', 'fav_nums', 'click_nums', 'image']
    list_filter = ['name', 'desc', 'detail', 'degree', 'learn_time', 'students', 'fav_nums', 'click_nums', 'image',
                   'add_time']
    inlines = [LessonAinline]

  • 同一model兩個注冊管理器

例如其中的輪播課程桐玻,可以分為兩個列表頁,其中一個是輪播課程界面荆萤,另一個是非輪播界面镊靴。

class BannerCourse(Course):
    """
    輪播圖課程
    """
    class Meta:
        verbose_name = u'輪播圖課程'
        verbose_name_plural = verbose_name
        proxy = True
# _*_ encoding:utf-8 _*_
from __future__ import unicode_literals
from datetime import datetime
from django.db import models

from organization.models import CourseOrg, Teacher

# Create your models here.


class Course(models.Model):
    course_org = models.ForeignKey(CourseOrg, verbose_name=u'課程機構(gòu)')
    name = models.CharField(max_length=128, verbose_name=u'課程名稱')
    desc = models.CharField(max_length=256, verbose_name=u'課程描述')
    category = models.CharField(default=u'后端開發(fā)', max_length=20, verbose_name=u'課程分類')
    detail = models.TextField(verbose_name=u'課程詳情')
    degree = models.CharField(choices=(('cj', '初級'), ('zj', '中級'), ('gj', '高級')), max_length=2, verbose_name=u'課程難度')
    learn_time = models.IntegerField(default=0, verbose_name=u'課程時長')
    students = models.IntegerField(default=0, verbose_name=u'學(xué)習(xí)人數(shù)')
    fav_nums = models.IntegerField(default=0, verbose_name=u'收藏人數(shù)')
    click_nums = models.IntegerField(default=0, verbose_name=u'點擊數(shù)')
    teacher = models.ForeignKey(Teacher, null=True, blank=True, verbose_name=u'教師外鍵')
    image = models.ImageField(upload_to='courses/%Y/%m', verbose_name=u'封面圖', max_length=128)
    tag = models.CharField(default='', max_length=20, verbose_name=u'課程標(biāo)簽')
    youneed_know = models.CharField(default='', max_length=256, verbose_name=u'課程須知')
    is_banner = models.BooleanField(default=False, verbose_name=u'是否是廣告欄')
    teacher_tell = models.CharField(default='', max_length=256, verbose_name=u'教師建議')
    add_time = models.DateTimeField(default=datetime.now, verbose_name=u'添加時間')

    class Meta:
        verbose_name = u'課程信息'
        verbose_name_plural = verbose_name

    def get_lesson_count(self):
        # 課程章節(jié)外鍵獲取總數(shù)
        return self.lesson_set.all().count()

    def get_students_list(self):
        # 根據(jù)用戶操作外鍵獲取學(xué)習(xí)用戶
        return self.usercourse_set.all()[:5]

    def ger_lesson_detail(self):
        # 獲取所有的章節(jié)信息
        return self.lesson_set.all()

    def __unicode__(self):
        return self.name


class BannerCourse(Course):
    """
    輪播圖課程
    """
    class Meta:
        verbose_name = u'輪播圖課程'
        verbose_name_plural = verbose_name
        proxy = True


class Lesson(models.Model):
    course = models.ForeignKey(Course, verbose_name=u'章節(jié)外鍵')
    name = models.CharField(max_length=128, verbose_name=u'章節(jié)名稱')
    add_time = models.DateTimeField(default=datetime.now, verbose_name=u'添加時間')

    class Meta:
        verbose_name = u'章節(jié)信息'
        verbose_name_plural = verbose_name

    def __unicode__(self):
        return self.name

    def get_video_info(self):
        # 獲取所有視屏信息
        return self.video_set.all()


class Video(models.Model):
    lesson = models.ForeignKey(Lesson, verbose_name=u'視頻')
    name = models.CharField(max_length=128, verbose_name=u'視頻名稱')
    url = models.CharField(default='', max_length=200, verbose_name=u'章節(jié)連接')
    learn_time = models.IntegerField(default=0, verbose_name=u'章節(jié)時長')
    add_time = models.DateTimeField(default=datetime.now, verbose_name=u'添加時間')

    class Meta:
        verbose_name = u'視頻信息'
        verbose_name_plural = verbose_name

    def __unicode__(self):
        return self.name


class CourseResource(models.Model):
    course = models.ForeignKey(Course, verbose_name=u'資源')
    download = models.FileField(upload_to='course/resource/%Y/%m', verbose_name=u'下載地址', max_length=128)
    name = models.CharField(max_length=128, verbose_name=u'資源名稱')
    add_time = models.DateTimeField(default=datetime.now, verbose_name=u'添加時間')

    class Meta:
        verbose_name = u'資源信息'
        verbose_name_plural = verbose_name

# _*_ encoding:utf-8 _*_

__author__ = 'wrj008'
__date__ = '2018/3/10 8:49'

import xadmin
from .models import Course, Lesson, Video, CourseResource, BannerCourse


class LessonAinline(object):
    model = Lesson
    extra = 0


class CourseAdmin(object):
    list_display = ['name', 'desc', 'detail', 'degree', 'learn_time', 'students', 'fav_nums', 'click_nums', 'image',
                    'add_time']
    search_fields = ['name', 'desc', 'detail', 'degree', 'learn_time', 'students', 'fav_nums', 'click_nums', 'image']
    list_filter = ['name', 'desc', 'detail', 'degree', 'learn_time', 'students', 'fav_nums', 'click_nums', 'image',
                   'add_time']
    inlines = [LessonAinline]

    def queryset(self):
        qs = super(CourseAdmin, self).queryset()
        qs = qs.filter(is_banner=False)
        return qs


class BannerCourseAdmin(object):
    list_display = ['name', 'desc', 'detail', 'degree', 'learn_time', 'students', 'fav_nums', 'click_nums', 'image',
                    'add_time']
    search_fields = ['name', 'desc', 'detail', 'degree', 'learn_time', 'students', 'fav_nums', 'click_nums', 'image']
    list_filter = ['name', 'desc', 'detail', 'degree', 'learn_time', 'students', 'fav_nums', 'click_nums', 'image',
                   'add_time']
    inlines = [LessonAinline]

    def queryset(self):
        qs = super(BannerCourseAdmin, self).queryset()
        qs = qs.filter(is_banner=True)
        return qs


class LessonAdmin(object):
    list_display = ['course', 'name', 'add_time']
    search_fields = ['course', 'name']
    list_filter = ['course', 'name', 'add_time']


class VideoAdmin(object):
    list_display = ['lesson', 'name', 'add_time']
    search_fields = ['lesson', 'name']
    list_filter = ['lesson', 'name', 'add_time']


class CourseResourceAdmin(object):
    list_display = ['course', 'download', 'name', 'add_time']
    search_fields = ['course', 'download', 'name']
    list_filter = ['course', 'download', 'name', 'add_time']


xadmin.site.register(Course, CourseAdmin)
xadmin.site.register(BannerCourse, BannerCourseAdmin)
xadmin.site.register(Lesson, LessonAdmin)
xadmin.site.register(Video, VideoAdmin)
xadmin.site.register(CourseResource, CourseResourceAdmin)

  • 函數(shù)顯示
  def get_lesson_count(self):
        # 課程章節(jié)外鍵獲取總數(shù)
        return self.lesson_set.all().count()

    get_lesson_count.short_description = '章節(jié)數(shù)'

    def go_to(self):
        from django.utils.safestring import mark_safe
        return mark_safe('<a href="www.baidu.com">跳轉(zhuǎn)</a>')
        
    
  • 頁面自動刷新
class CourseAdmin(object):
    list_display = ['name', 'desc', 'detail', 'degree', 'learn_time', 'students', 'fav_nums', 'click_nums', 'image',
                    'add_time']
    search_fields = ['name', 'desc', 'detail', 'degree', 'learn_time', 'students', 'fav_nums', 'click_nums', 'image']
    list_filter = ['name', 'desc', 'detail', 'degree', 'learn_time', 'students', 'fav_nums', 'click_nums', 'image',
                   'add_time']
    inlines = [LessonAinline]
    refresh_times = [3, 5]

    def queryset(self):
        qs = super(CourseAdmin, self).queryset()
        qs = qs.filter(is_banner=False)
        return qs
  • 課程保存铣卡,機構(gòu)中課程數(shù)量更新
class CourseAdmin(object):
    list_display = ['name', 'desc', 'detail', 'degree', 'learn_time', 'students', 'fav_nums', 'click_nums', 'image',
                    'add_time']
    search_fields = ['name', 'desc', 'detail', 'degree', 'learn_time', 'students', 'fav_nums', 'click_nums', 'image']
    list_filter = ['name', 'desc', 'detail', 'degree', 'learn_time', 'students', 'fav_nums', 'click_nums', 'image',
                   'add_time']
    inlines = [LessonAinline]
    refresh_times = [3, 5]

    def queryset(self):
        qs = super(CourseAdmin, self).queryset()
        qs = qs.filter(is_banner=False)
        return qs

    def save_models(self):
        """
        課程保存機構(gòu)課程數(shù)更新
        """
        obj = self.new_obj
        obj.save()
        if obj.course_org is not None:
            course_org = obj.course_org
            course_org.course_nums = Course.objects.filter(course_org=course_org).count()
            course_org.save()

富文本集成

富文本
某個字段使用某種樣式
style_fields = {'detail': 'ueditor'}
  • django-ueditor 開源富文本文件插件功能開發(fā)

github 開源項目地址

1.進入文件目錄
cd ****
workon '虛擬環(huán)境'
python setup.py install

2.如果1沒效果,則采用源碼放入本地第三方保重偏竟,和xadmin一個文件夾下

壓縮包中的DjangoUeditor文件


注冊
INSTALLED_APPS = [
    'DjangoUeditor',
]
配置url
 # richtext url
    url(r'^ueditor/', include('DjangoUeditor.urls'))
    
model字段進行變更
from DjangoUeditor.models import UEditorField 

    detail = UEditorField(verbose_name=u'課程詳情', width=600, height=300, toolbars="full", imagePath="course/ueditor/", filePath="course/ueditor/", default='')

plugin插件變更

# _*_ encoding:utf-8 _*_

__author__ = 'wrj008'
__date__ = '2018/3/19 16:41'
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")         #自己的靜態(tài)目錄
        js += '<script type="text/javascript" src="%s"></script>' % (settings.STATIC_URL + "ueditor/ueditor.all.min.js")   #自己的靜態(tài)目錄
        nodes.append(js)

xadmin.site.register_plugin(UeditorPlugin, UpdateAdminView)
xadmin.site.register_plugin(UeditorPlugin, CreateAdminView)

注冊插件

將ueditor添加到plugin下的_init_中
PLUGINS = (
    ...
    'ueditor',
)

引用

class CourseAdmin(object):
    list_display = ['name', 'desc', 'detail', 'degree', 'learn_time', 'students', 'fav_nums', 'click_nums', 'image',
                    'add_time']
    search_fields = ['name', 'desc', 'detail', 'degree', 'learn_time', 'students', 'fav_nums', 'click_nums', 'image']
    list_filter = ['name', 'desc', 'detail', 'degree', 'learn_time', 'students', 'fav_nums', 'click_nums', 'image',
                   'add_time']
    inlines = [LessonAinline]
    refresh_times = [3, 5]
    style_fields = {'detail': 'ueditor'}

    def queryset(self):
        qs = super(CourseAdmin, self).queryset()
        qs = qs.filter(is_banner=False)
        return qs

    def save_models(self):
        """
        課程保存機構(gòu)課程數(shù)更新
        """
        obj = self.new_obj
        obj.save()
        if obj.course_org is not None:
            course_org = obj.course_org
            course_org.course_nums = Course.objects.filter(course_org=course_org).count()
            course_org.save()
詳情頁面展示
<div class="tab_cont tab_cont1">
    {% autoescape off %}
        {{ course.detail }}
    {% endautoescape %}

</div>

  • 本篇博客原視頻博主[慕課在線教育平臺]
  • 本篇博客撰寫人: XiaoJinZi 轉(zhuǎn)載請注明出處
  • 學(xué)生能力有限 附上郵箱: 986209501@qq.com 不足以及誤處請大佬指責(zé)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末煮落,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子踊谋,更是在濱河造成了極大的恐慌蝉仇,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件殖蚕,死亡現(xiàn)場離奇詭異轿衔,居然都是意外死亡,警方通過查閱死者的電腦和手機睦疫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門害驹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人笼痛,你說我怎么就攤上這事裙秋±虐瑁” “怎么了缨伊?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長进宝。 經(jīng)常有香客問我刻坊,道長,這世上最難降的妖魔是什么党晋? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任谭胚,我火速辦了婚禮,結(jié)果婚禮上未玻,老公的妹妹穿的比我還像新娘灾而。我一直安慰自己,他們只是感情好扳剿,可當(dāng)我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布旁趟。 她就那樣靜靜地躺著,像睡著了一般庇绽。 火紅的嫁衣襯著肌膚如雪锡搜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天瞧掺,我揣著相機與錄音耕餐,去河邊找鬼。 笑死辟狈,一個胖子當(dāng)著我的面吹牛肠缔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼桩砰,長吁一口氣:“原來是場噩夢啊……” “哼拓春!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起亚隅,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤硼莽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后煮纵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體懂鸵,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年行疏,在試婚紗的時候發(fā)現(xiàn)自己被綠了匆光。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡酿联,死狀恐怖终息,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情贞让,我是刑警寧澤周崭,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站喳张,受9級特大地震影響续镇,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜销部,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一摸航、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧舅桩,春花似錦酱虎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至歼指,卻和暖如春爹土,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背踩身。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工胀茵, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人挟阻。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓琼娘,卻偏偏與公主長得像峭弟,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子脱拼,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,055評論 2 355

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