Django+xadmin打造在线教育平台(一)

操作系统:windows 10

Python: 3.7.1

Django: 2.0.6

一、项目创建

浏览原始的前端页面,从页面上进行模块划分,抽象出APP,分析各个APP,初步抽取出APP模型和模型字段,从页面上分析整个项目模板的继承关系。

1、项目模块划分以及各个APP模型抽象

Django+xadmin打造在线教育平台(一)

 2、创建项目

Django项目我们可以通过用命令的方式创建,也可以直接使用Pycharm创建,为了方便直接使用Pycharm创建

(1)命令行创建Django项目

django-admin startproject GuLiEdu

(2)Pycharm创建

打开Pycharm,创建项目,选择Django

Django+xadmin打造在线教育平台(一)

3、创建App

(1)创建App

python manage.py startapp users    # 如果在创建项目时候创建,就不用重复创建

python manage.py startapp courses

python manage.py startapp orgs

python manage.py startapp operations

(2)修改settings文件

①、注册app

将我们刚才创建的app注册到Django中,在INSTALLED_APPS中添加我们创建的app名称

Django+xadmin打造在线教育平台(一)

 ②、数据库配置

DATABASES = {
    ‘default‘: {
        ‘ENGINE‘: ‘django.db.backends.mysql‘,
        ‘NAME‘: ‘guliedu‘,   # 需要去数据库创建
        ‘USER‘: ‘root‘,
        ‘PASSWORD‘: ‘123456‘,
        ‘HOST‘: ‘127.0.0.1‘,
        ‘PORT‘: 3306
    }
}

③、国际化设置

LANGUAGE_CODE = ‘zh-hans‘

TIME_ZONE = ‘Asia/Shanghai‘

USE_I18N = True

USE_L10N = True

USE_TZ = False

④、静态文件路径配置 

STATIC_URL = ‘/static/‘
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, ‘static‘)
]

⑤设置媒体访问路径

MEDIA_URL = ‘/static/media/‘
MEDIA_ROOT = os.path.join(BASE_DIR, ‘static/media‘)

(3)路由配置

①子路由

分别在四个app中建立urls.py文件,并做简单配置

from django.urls import path

app_name = app名称

urlpatterns = [

]

②总路由

在GuLiEdu目录下的urls中配置分发

from django.urls import path, include

urlpatterns = [
    path(‘admin/‘, admin.site.urls),
    path(‘users/‘, include(‘users.urls‘, namespace=‘users‘)),
    path(‘courses/‘, include(‘courses.urls‘, namespace=‘courses‘)),
    path(‘orgs/‘, include(‘orgs.urls‘, namespace=‘orgs‘)),
    path(‘operations/‘, include(‘operations.urls‘, namespace=‘operations‘)),
]

(4)、建立数据模型类

①用户users里面models设计

from django.db import models
from django.contrib.auth.models import AbstractUser
from datetime import datetime
# Create your models here.


class UserProfile(AbstractUser):
    image = models.ImageField(upload_to=‘user/‘, max_length=200, verbose_name=‘用户头像‘, null=True, blank=True)
    nick_name = models.CharField(max_length=20, verbose_name=‘用户昵称‘, null=True, blank=True)
    birthday = models.DateTimeField(verbose_name=‘用户生日‘, null=True, blank=True)
    gender = models.CharField(choices=((‘girl‘, ‘女‘), (‘boy‘, ‘男‘)), max_length=10, verbose_name=‘用户性别‘, default=‘girl‘)
    address = models.CharField(max_length=200, verbose_name=‘用户地址‘, null=True, blank=True)
    phone = models.CharField(max_length=11, verbose_name=‘用户手机‘, null=True, blank=True)
    add_time = models.DateTimeField(default=datetime.now, verbose_name=‘添加时间‘)

    def __str__(self):
        return self.username

    class Meta:
        verbose_name = ‘用户信息‘
        verbose_name_plural = verbose_name


class BannerInfo(models.Model):
    image = models.ImageField(upload_to=‘banner/‘, verbose_name=‘轮播图片‘, max_length=200)
    url = models.URLField(default=‘http://www.atguigu.com‘, max_length=200, verbose_name=‘图片链接‘)
    add_time = models.DateTimeField(default=datetime.now, verbose_name=‘添加时间‘)

    def __str__(self):
        return str(self.image)

    class Meta:
        verbose_name = ‘轮播图信息‘
        verbose_name_plural = verbose_name


class EmailVerify(models.Model):
    code = models.CharField(max_length=20, verbose_name=‘邮箱验证码‘)
    email = models.EmailField(max_length=200, verbose_name=‘验证码邮箱‘)
    send_type = models.IntegerField(choices=((1, ‘register‘), (2, ‘forget‘), (3, ‘change‘)), verbose_name=‘验证码类型‘)
    add_time = models.DateTimeField(default=datetime.now, verbose_name=‘添加时间‘)

    def __str__(self):
        return str(self.code)

    class Meta:
        verbose_name = ‘邮箱验证码‘
        verbose_name_plural = verbose_name

users/model

用户表的设计,通过继承扩展Django内部auth模块自带的user表,生成我们自己的用户UserProfile表。注意:当使用继承后,需要在settings配置用户默认模型为自己创建的这个表,要不还是内部的user表settings设置如下:

AUTH_USER_MODEL = ‘users.UserProfile‘

②机构orgs里面models设计

from django.db import models
from datetime import datetime
# Create your models here.


class CityInfo(models.Model):
    name = models.CharField(max_length=20, verbose_name=‘城市名称‘)
    add_time = models.DateTimeField(default=datetime.now, verbose_name=‘添加时间‘)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = ‘城市信息‘
        verbose_name_plural = verbose_name


class OrgInfo(models.Model):
    image = models.ImageField(upload_to=‘org/‘, max_length=200, verbose_name=‘机构封面‘)
    name = models.CharField(max_length=20, verbose_name=‘机构名称‘)
    course_num = models.IntegerField(default=0, verbose_name=‘课程数‘)
    study_num = models.IntegerField(default=0, verbose_name=‘学习人数‘)
    address = models.CharField(max_length=200, verbose_name=‘机构地址‘)
    desc = models.CharField(max_length=200, verbose_name=‘机构简介‘)
    detail = models.TextField(verbose_name=‘机构详情‘)
    love_num = models.IntegerField(default=0, verbose_name=‘收藏数‘)
    click_num = models.IntegerField(default=0, verbose_name=‘访问量‘)
    category = models.CharField(choices=((‘pxjg‘, ‘培训机构‘), (‘gx‘, ‘高校‘), (‘gr‘, ‘个人‘)), max_length=10, verbose_name=‘机构类别‘)
    cityinfo = models.ForeignKey(CityInfo, verbose_name=‘所在城市‘, on_delete=models.CASCADE)
    add_time = models.DateTimeField(default=datetime.now, verbose_name=‘添加时间‘)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = ‘机构信息‘
        verbose_name_plural = verbose_name


class TeacherInfo(models.Model):
    image = models.ImageField(upload_to=‘teacher/‘, max_length=200, verbose_name=‘讲师头像‘)
    name = models.CharField(max_length=20, verbose_name=‘讲师姓名‘)
    work_year = models.CharField(default=3, max_length=5,  verbose_name=‘工作年限‘)
    work_position = models.CharField(max_length=20, verbose_name=‘工作职位‘)
    work_style = models.CharField(max_length=20, verbose_name=‘教学特点‘)
    work_company = models.ForeignKey(OrgInfo, verbose_name=‘所属机构‘, on_delete=models.CASCADE)
    age = models.IntegerField(default=30, verbose_name=‘讲师年龄‘)
    gender = models.CharField(choices=((‘boy‘, ‘男‘), (‘girl‘, ‘女‘)), max_length=10, verbose_name=‘讲师性别‘, default=‘girl‘)
    love_num = models.IntegerField(default=0, verbose_name=‘收藏数‘)
    click_num = models.IntegerField(default=0, verbose_name=‘访问量‘)
    add_time = models.DateTimeField(default=datetime.now, verbose_name=‘添加时间‘)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = ‘讲师信息‘
        verbose_name_plural = verbose_name

orgs/models

③课程courses里面models设计

from django.db import models
from datetime import datetime

# Create your models here.
from orgs.models import OrgInfo, TeacherInfo


class CourseInfo(models.Model):
    image = models.ImageField(upload_to=‘course/‘, max_length=200, verbose_name=‘课程封面‘)
    name = models.CharField(max_length=20, verbose_name=‘课程名称‘)
    study_time = models.IntegerField(default=0, verbose_name=‘学习时长‘)
    study_num = models.IntegerField(default=0, verbose_name=‘学习人数‘)
    level = models.CharField(choices=((‘cj‘, ‘初级‘), (‘zj‘, ‘中级‘), (‘gj‘, ‘高级‘)), max_length=10, default=‘cj‘, verbose_name=‘课程难度‘)
    love_num = models.IntegerField(default=0, verbose_name=‘收藏数‘)
    click_num = models.IntegerField(default=0, verbose_name=‘访问量‘)
    desc = models.CharField(max_length=200, verbose_name=‘课程简介‘)
    detail = models.TextField(verbose_name=‘课程详情‘)
    category = models.CharField(choices=((‘qd‘, ‘前端开发‘), (‘hd‘, ‘后端开发‘)), max_length=10, verbose_name=‘课程类别‘)
    course_notice = models.CharField(max_length=200, verbose_name=‘课程公告‘)
    course_need = models.CharField(max_length=100, verbose_name=‘课程须知‘)
    teacher_tell = models.CharField(max_length=100, verbose_name=‘老师教导‘)
    orginfo = models.ForeignKey(OrgInfo, verbose_name=‘所属机构‘, on_delete=models.CASCADE)
    teacherinfo = models.ForeignKey(TeacherInfo, verbose_name=‘所属讲师‘, on_delete=models.CASCADE)
    add_time = models.DateTimeField(default=datetime.now, verbose_name=‘添加时间‘)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = ‘课程表‘
        verbose_name_plural = verbose_name


class LessonInfo(models.Model):
    name = models.CharField(max_length=50, verbose_name=‘章节名称‘)
    courseinfo = models.ForeignKey(CourseInfo, verbose_name=‘所属课程‘, on_delete=models.CASCADE)
    add_time = models.DateTimeField(default=datetime.now, verbose_name=‘添加时间‘)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = ‘章节信息‘
        verbose_name_plural = verbose_name


class VideoInfo(models.Model):
    name = models.CharField(max_length=50, verbose_name=‘视频名称‘)
    study_time = models.IntegerField(default=0, verbose_name=‘视频时长‘)
    url = models.URLField(default=‘http://www.atguigu.com‘, verbose_name=‘视频链接‘, max_length=200)
    lessoninfo = models.ForeignKey(LessonInfo, verbose_name=‘所属章节‘, on_delete=models.CASCADE)
    add_time = models.DateTimeField(default=datetime.now, verbose_name=‘添加时间‘)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = ‘视频信息‘
        verbose_name_plural = verbose_name


class SourceInfo(models.Model):
    name = models.CharField(max_length=50, verbose_name=‘视频名称‘)
    down_load = models.FileField(upload_to=‘source/‘, max_length=200, verbose_name=‘下载路径‘)
    courseinfo = models.ForeignKey(CourseInfo, verbose_name=‘所属课程‘, on_delete=models.CASCADE)
    add_time = models.DateTimeField(default=datetime.now, verbose_name=‘添加时间‘)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = ‘资源信息‘
        verbose_name_plural = verbose_name

courses/models

在settings文件中,添加图片处理器,为了在课程列表中前面加上MEDIA_URL

‘django.template.context_processors.media‘,  # 添加图片处理器,为了在课程列表中前面加上MEDIA_URL

Django+xadmin打造在线教育平台(一)

④用户操作operations里面models设计

from django.db import models
from datetime import datetime

from courses.models import CourseInfo
from users.models import UserProfile
# Create your models here.


class UserAsk(models.Model):
    name = models.CharField(max_length=30, verbose_name=‘姓名‘)
    phone = models.CharField(max_length=11, verbose_name=‘手机‘)
    course = models.CharField(max_length=20, verbose_name=‘课程‘)
    add_time = models.DateTimeField(default=datetime.now, verbose_name=‘添加时间‘)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = ‘咨询信息‘
        verbose_name_plural = verbose_name


class UserLove(models.Model):
    love_man = models.ForeignKey(UserProfile, verbose_name=‘收藏用户‘, on_delete=models.CASCADE)
    love_id = models.IntegerField(verbose_name=‘收藏ID‘)  # 可以是机构,课程,老师
    love_type = models.IntegerField(choices=((1, ‘org‘), (2, ‘course‘), (3, ‘teacher‘)), verbose_name=‘收藏类别‘)
    love_status = models.BooleanField(default=False, verbose_name=‘收藏状态‘)
    add_time = models.DateTimeField(default=datetime.now, verbose_name=‘添加时间‘)

    def __str__(self):
        return self.love_man.username

    class Meta:
        verbose_name = ‘收藏信息‘
        verbose_name_plural = verbose_name


class UserCourse(models.Model):
    study_man = models.ForeignKey(UserProfile, verbose_name=‘学习用户‘, on_delete=models.CASCADE)
    study_course = models.ForeignKey(CourseInfo, verbose_name=‘学习课程‘, on_delete=models.CASCADE)
    add_time = models.DateTimeField(default=datetime.now, verbose_name=‘添加时间‘)

    def __str__(self):
        return self.study_man

    class Meta:
        unique_together = (‘study_man‘, ‘study_course‘)   # 联合唯一
        verbose_name = ‘用户学习信息‘
        verbose_name_plural = verbose_name


class UserComment(models.Model):
    comment_man = models.ForeignKey(UserProfile, verbose_name=‘评论用户‘, on_delete=models.CASCADE)
    comment_course = models.ForeignKey(CourseInfo, verbose_name=‘评论课程‘, on_delete=models.CASCADE)
    comment_content = models.CharField(max_length=300, verbose_name=‘评论内容‘)
    add_time = models.DateTimeField(default=datetime.now, verbose_name=‘添加时间‘)

    def __str__(self):
        return self.comment_content

    class Meta:
        verbose_name = ‘用户课程信息‘
        verbose_name_plural = verbose_name


class UserMessage(models.Model):
    message_man = models.IntegerField(default=0, verbose_name=‘消息用户‘)  # 如果id为0,系统消息
    message_content = models.CharField(max_length=200, verbose_name=‘消息内容‘)
    message_status = models.BooleanField(default=False, verbose_name=‘消息状态‘)
    add_time = models.DateTimeField(default=datetime.now, verbose_name=‘添加时间‘)

    def __str__(self):
        return self.message_content

    class Meta:
        verbose_name = ‘用户消息‘
        verbose_name_plural = verbose_name

operations/models

4、整合4个app到apps

根目录下创建apps包,将四个app分别拖入包中,不要选“Search for references”

Django+xadmin打造在线教育平台(一)

 如果选择,搜索还是从原始路径去搜索。

在apps上右键MarksourceRoot

设置settings文件,为其加上python环境变量。

import os   # 代表系统环境
import sys  # 代表python环境

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# 将我们自己定义的包加入到Python搜寻环境变量当中
sys.path.insert(0, os.path.join(BASE_DIR, ‘Apps‘))

5、迁移数据库

python manage.py makemigrations

python manage.py migrate

二、xadmin的使用

1、xadmin的简介

http://sshwsfc.github.io/xadmin/   xadmin的官网

xadmin是一个Django的管理后台实现,使用了更加灵活的架构设计及Bootstrap UI框架, 目的是替换现有的admin,国人开发,有许多新的特性。详情参考上面xadmin官方网站。

2、xadmin的下载和安装(源码包安装)

(1)下载

在xadmin官方网站上我们可以看到xadmin的介绍,并且我们也可以发现xadmin的源码被托管在GitHub上,因此,我们可以去GitHub轻松获取到xadmin源码进行安装。

Django+xadmin打造在线教育平台(一)

点击如图所示按钮后,我们可以通过git clone的方式或者直接选择下载zip的方式可以获取到xadmin的源码下载包。

(2)安装

a、 复制xadmin文件夹到我们的项目根目录当中

b、 创建extra_apps放置第三方的app,将xadmin移动到我们这个extra_apps下

c、 将extra_apps mark为root_source

d、 将extra_apps在setting当中配置好搜索路径 

sys.path.insert(0, os.path.join(BASE_DIR, ‘extra_apps‘))

e、 依赖包装完之后,再去install当中添加上app

f、将xadmin和crispy_forms添加到我们的installed_apps

g、在总路由urls.py中将我们本来的admin注释掉改为我们xadmin

import xadmin

from django.urls import path, include

urlpatterns = [
    path(‘xadmin/‘, xadmin.site.urls),
    path(‘users/‘, include(‘users.urls‘, namespace=‘users‘)),
    path(‘courses/‘, include(‘courses.urls‘, namespace=‘courses‘)),
    path(‘orgs/‘, include(‘orgs.urls‘, namespace=‘orgs‘)),
    path(‘operations/‘, include(‘operations.urls‘, namespace=‘operations‘)),
]

h、再次执行迁移同步,目的是为了生成xadmin所依赖的表

i、创建超级管理员,去验证xadmin是否安装成功

python manage.py  createsuperuser

Django+xadmin打造在线教育平台(一)

 (3)、xadmin的注册

在相应的app当中创建adminx.py文件,导入xadmin以及models中的模型,下面以users示例

import xadmin
from .models import BannerInfo, EmailVerifyCode


class BannerInfoXadmin(object):   
    list_display = [‘image‘, ‘url‘, ‘add_time‘]  # 显示
    search_fields = [‘image‘, ‘url‘]  # 搜索框
    list_filter = [‘image‘, ‘url‘]  # 过滤器


class EmailVerifyCodeXadmin(object):
    list_display = [‘code‘, ‘email‘, ‘send_type‘, ‘add_time‘]


xadmin.site.register(BannerInfo, BannerInfoXadmin)  # 注册
xadmin.site.register(EmailVerifyCode, EmailVerifyCodeXadmin)

Django+xadmin打造在线教育平台(一)

 如上图所示,左侧显示了轮播图信息以及邮箱验证码两个模型,在轮播图信息中,我们添加了过滤器以及搜索框。

另外三个app方法与users类似。

import xadmin
from .models import CityInfo,OrgInfo,TeacherInfo


class CityInfoXadmin(object):
   list_display = [‘name‘, ‘add_time‘]


class OrgInfoXadmin(object):
    list_display = [‘image‘, ‘name‘, ‘course_num‘, ‘study_num‘, ‘love_num‘, ‘click_num‘,‘category‘, ‘cityinfo‘]


class TeacherInfoXadmin(object):
    list_display = [‘image‘, ‘name‘, ‘work_year‘, ‘work_position‘, ‘work_style‘, ‘work_company‘, ‘age‘, ‘gender‘,
                    ‘love_num‘, ‘click_num‘]


xadmin.site.register(CityInfo, CityInfoXadmin)
xadmin.site.register(OrgInfo, OrgInfoXadmin)
xadmin.site.register(TeacherInfo, TeacherInfoXadmin)

orgs/xadmin.py

import xadmin
from .models import *


class CourseInfoXadmin(object):
    list_display = [‘image‘,‘name‘,‘study_num‘,‘level‘,‘love_num‘,‘category‘,‘orginfo‘,‘teacherinfo‘]


class LessonInfoXadmin(object):
    list_display = [‘name‘, ‘courseinfo‘, ‘add_time‘]


class VideoInfoXadmin(object):
    list_display = [‘name‘, ‘study_time‘, ‘url‘, ‘lessoninfo‘]


class SourceInfoXadmin(object):
    list_display = [‘name‘, ‘down_load‘, ‘courseinfo‘, ‘add_time‘]


xadmin.site.register(CourseInfo,CourseInfoXadmin)
xadmin.site.register(LessonInfo,LessonInfoXadmin)
xadmin.site.register(VideoInfo,VideoInfoXadmin)
xadmin.site.register(SourceInfo,SourceInfoXadmin)

course/adminx.py

import xadmin
from .models import *


class UserAskXadmin(object):
    list_display = [‘name‘, ‘phone‘, ‘course‘, ‘add_time‘]


class UserLoveXadmin(object):
    list_display = [‘love_man‘, ‘love_id‘, ‘love_type‘, ‘love_status‘, ‘add_time‘]


class UserCourseXadmin(object):
    list_display = [‘study_man‘, ‘study_course‘, ‘add_time‘]


class UserCommentXadmin(object):
    list_display = [‘comment_man‘, ‘comment_course‘, ‘comment_content‘, ‘add_time‘]


class UserMessageXadmin(object):
    list_display = [‘message_man‘, ‘message_content‘, ‘message_status‘, ‘add_time‘]



xadmin.site.register(UserAsk, UserAskXadmin)
xadmin.site.register(UserCourse, UserCourseXadmin)
xadmin.site.register(UserComment, UserCommentXadmin)
xadmin.site.register(UserMessage, UserMessageXadmin)

operations/adminx.py

(4)、将xadmin后台名字改为自己定的名字

方法一:在app当中apps.py文件当中,最下面添加verbose_name=’自定义名字’

方法二: 在app当中的__init__文件当中添加配置

default_app_config = "orgs.apps.OrgsConfig"
说明:可以在installed_apps中安装应用的时候,按照users自动安装的方式去做安装,那么这个__init__文件中的配置也可以省略这里演示将在settings文件中,修改app注册安装方式,然后采用方法一修改字段
INSTALLED_APPS = [
    ‘django.contrib.admin‘,
    ‘django.contrib.auth‘,
    ‘django.contrib.contenttypes‘,
    ‘django.contrib.sessions‘,
    ‘django.contrib.messages‘,
    ‘django.contrib.staticfiles‘,
    ‘users.apps.UsersConfig‘,
    ‘courses.apps.CoursesConfig‘,
    ‘orgs.apps.OrgsConfig‘,
    ‘operations.apps.OperationsConfig‘,
    ‘xadmin‘,
    ‘crispy_forms‘
]

(5)、Xadmin后台全局配置

所有的配置都放在users/adminx.py中

①、添加主题

# 配置xadmin主题,注册的时候要用到专用的view去注册
class BaseXadminSetting(object):
    enable_themes = True  # 主题
    use_bootswatch = True   # 自带主题

xadmin.site.register(views.BaseAdminView, BaseXadminSetting)  # 注册主题

②、左侧列表字段“收起”以及标题和底部

class GlobalXadminSetting(object):  # 标题和底部公司名称
    site_title = ‘Egon人生无限‘
    site_footer = ‘小姑娘快过来,让我摸一下屁股‘
    menu_style = ‘accordion‘  # 菜单收起


xadmin.site.register(views.CommAdminView, GlobalXadminSetting)  # 注册标题和底部公司名称
import xadmin
from .models import BannerInfo, EmailVerifyCode
from xadmin import views


# 配置xadmin主题,注册的时候要用到专用的view去注册
class BaseXadminSetting(object):
    enable_themes = True  # 主题
    use_bootswatch = True   # 自带主题


class GlobalXadminSetting(object):  # 标题和底部公司名称
    site_title = ‘Egon人生无限‘
    site_footer = ‘小姑娘快过来,让我摸一下屁股‘
    menu_style = ‘accordion‘   # 列表菜单收起


class BannerInfoXadmin(object):
    list_display = [‘image‘, ‘url‘, ‘add_time‘]  # 显示
    search_fields = [‘image‘, ‘url‘]  # 搜索框
    list_filter = [‘image‘, ‘url‘]  # 过滤器


class EmailVerifyCodeXadmin(object):
    list_display = [‘code‘, ‘email‘, ‘send_type‘, ‘add_time‘]


xadmin.site.register(views.BaseAdminView, BaseXadminSetting)  # 注册主题
xadmin.site.register(views.CommAdminView, GlobalXadminSetting)  # 注册标题和底部公司名称
xadmin.site.register(BannerInfo, BannerInfoXadmin)
xadmin.site.register(EmailVerifyCode, EmailVerifyCodeXadmin)

adminx.py完整代码

Django+xadmin打造在线教育平台(一)

 

相关推荐