Django+xadmin打造在线教育平台

Posted huiyichanmian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django+xadmin打造在线教育平台相关的知识,希望对你有一定的参考价值。

操作系统:windows 10

Python: 3.7.1

Django: 2.0.6

 

一、项目创建

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

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

技术图片

 

 

 2、创建项目

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

(1)命令行创建Django项目

 

django-admin startproject GuLiEdu

 

(2)Pycharm创建

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

技术图片

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名称

技术图片

 

 

 ②、数据库配置

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

技术图片

④用户操作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”

技术图片

 

 

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

在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源码进行安装。

技术图片

 

 

 

点击如图所示按钮后,我们可以通过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

技术图片

 

 

 (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)

技术图片

 

 

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

另外三个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打造在线教育平台的主要内容,如果未能解决你的问题,请参考以下文章

Django+xadmin打造在线教育平台

Django+xadmin打造在线教育平台

Django+xadmin打造在线教育平台

Django+xadmin打造在线教育平台

第三百七十九节,Django+Xadmin打造上线标准的在线教育平台—xadmin的安装

Django+xadmin打造在线教育平台