美文网首页django
Django+Xadmin打造在线教育系统(一)

Django+Xadmin打造在线教育系统(一)

作者: 听你讲故事啊 | 来源:发表于2018-09-17 20:20 被阅读195次

    系统概括:

    • 系统具有完整的用户登录注册以及找回密码功能,拥有完整个人中心。
    • 个人中心: 修改头像,修改密码,修改邮箱,可以看到我的课程以及我的收藏。可以删除收藏,我的消息。
    • 导航栏: 公开课,授课讲师,授课机构,全局搜索。
    • 点击公开课–> 课程列表,排序-搜索。热门课程推荐,课程的分页。
    • 点击课程–> 课程详情页中对课程进行收藏,取消收藏。富文本展示课程内容。
    • 点击开始学习–> 课程的章节信息,课程的评论信息。课程资源的下载链接。
    • 点击授课讲师–>授课讲师列表页,对讲师进行人气排序以及分页,右边有讲师排行榜。
    • 点击讲师的详情页面–> 对讲师进行收藏和分享,以及讲师的全部课程。
    • 导航栏: 授课机构有分页,排序筛选功能。
    • 机构列表页右侧有快速提交我要学习的表单。
    • 点击机构–> 左侧:机构首页,机构课程,机构介绍,机构讲师。
    • 后台管理系统可以切换主题。左侧每一个功能都有列表显示, 增删改查,筛选功能。
    • 课程列表页可以对不同字段进行排序。选择多条记录进行删除操作。
    • 课程列表页:过滤器->选择字段范围等,搜索,导出csv,xml,json。
    • 课程新增页面上传图片,富文本的编辑。时间选择,添加章节,添加课程资源。
    • 日志记录:记录后台人员的操作

    环境

    python == 3.6

    django == 2.0

    创建工程

    django-admin startproject MxOnline
    

    配置settings.py文件

    # 数据库
    
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'imooc',        #数据库名字
            'USER': 'root',          #账号
            'PASSWORD': '123456',      #密码
            'HOST': '127.0.0.1',    #IP
            'PORT': '3306',                   #端口
        }
    }
    
    
    # 使用中文
    LANGUAGE_CODE = 'zh-hans'
    
    TIME_ZONE = 'Asia/Shanghai'
    
    USE_I18N = True
    
    USE_L10N = True
    
    USE_TZ = False
    
    
    # 静态文件路径(须在根目录下创建static目录)
    
    STATIC_URL = '/static/'
    STATICFILES_DIRS = (
        os.path.join(BASE_DIR, 'static'),
    )
    

    数据库设计

    创建四个app,并将其添加到INSTALLED_APPS

    python manage.py startapp users
    
    python manage.py startapp course
    
    python manage.py startapp organization
    
    python manage.py startapp operation
    
    #  settings.py
    
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'users',
        'course',
        'operation',
        'organization',
    ]
    

    在根目录下新建一个apps文件夹,将创建的四个app文件拖到apps文件夹下,大致结构

    TIM截图20180906203453.png

    将apps目录添加到项目路径中

    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    sys.path.insert(0,os.path.join(BASE_DIR,'apps'))
    

    重载UserProfile

    # 使用自己写的UserProfile,而不是系统的
    AUTH_USER_MODEL = 'users.UserProfile'
    

    users modesl.py设计

    from datetime import datetime
    
    from django.contrib.auth.models import AbstractUser
    from django.db import models
    
    
    class UserProfile(AbstractUser):
        # 自定义的性别选择规则
        GENDER_CHOICES = (
            ("male", u"男"),
            ("female", u"女")
        )
        # 昵称
        nick_name = models.CharField(max_length=50, verbose_name=u"昵称", default="")
        # 生日,可以为空
        birthday = models.DateField(verbose_name=u"生日", null=True, blank=True)
        # 性别 只能男或女,默认女
        gender = models.CharField(
            max_length=6,
            verbose_name=u"性别",
            choices=GENDER_CHOICES,
            default="female")
        # 地址
        address = models.CharField(max_length=100, verbose_name="地址", default="")
        # 电话
        mobile = models.CharField(max_length=11, null=True, blank=True)
        # 头像 默认使用default.png
        image = models.ImageField(
            upload_to="image/%Y/%m",
            default=u"image/default.png",
            max_length=100
        )
    
        # meta信息,即后台栏目名
        class Meta:
            verbose_name = "用户信息"
            verbose_name_plural = verbose_name
    
        # 重载str方法,打印实例会打印username,username为继承自abstractuser
        def __str__(self):
            return self.username
    
    
    # 邮箱验证码model
    class EmailVerifyRecord(models.Model):
        SEND_CHOICES = (
            ("register", u"注册"),
            ("forget", u"找回密码")
        )
        code = models.CharField(max_length=20, verbose_name=u"验证码")
        # 未设置null = true blank = true 默认不可为空
        email = models.EmailField(max_length=50, verbose_name=u"邮箱")
        send_type = models.CharField(choices=SEND_CHOICES, max_length=10)
        # 这里的now得去掉(),不去掉会根据编译时间。而不是根据实例化时间。
        send_time = models.DateTimeField(default=datetime.now)
    
        class Meta:
            verbose_name = "邮箱验证码"
            verbose_name_plural = verbose_name
    
    
    # 轮播图model
    class Banner(models.Model):
        title = models.CharField(max_length=100, verbose_name=u"标题")
        image = models.ImageField(
            upload_to="banner/%Y/%m",
            verbose_name=u"轮播图",
            max_length=100)
        url = models.URLField(max_length=200, verbose_name=u"访问地址")
        # 默认index很大靠后。想要靠前修改index值。
        index = models.IntegerField(default=100, verbose_name=u"顺序")
        add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加时间")
    
        class Meta:
            verbose_name = u"轮播图"
            verbose_name_plural = verbose_name
    

    course models.py编写

    from datetime import datetime
    
    # 课程信息表
    from django.db import models
    
    
    class Course(models.Model):
        DEGREE_CHOICES = (
            ("cj", u"初级"),
            ("zj", u"中级"),
            ("gj", u"高级")
        )
        name = models.CharField(max_length=50, verbose_name=u"课程名")
        desc = models.CharField(max_length=300, verbose_name=u"课程描述")
        # TextField允许我们不输入长度。可以输入到无限大。暂时定义为TextFiled,之后更新为富文本
        detail = models.TextField(verbose_name=u"课程详情")
        degree = models.CharField(choices=DEGREE_CHOICES, max_length=2)
        # 使用分钟做后台记录(存储最小单位)前台转换
        learn_times = models.IntegerField(default=0, verbose_name=u"学习时长(分钟数)")
        # 保存学习人数:点击开始学习才算
        students = models.IntegerField(default=0, verbose_name=u"学习人数")
        fav_nums = models.IntegerField(default=0, verbose_name=u"收藏人数")
        image = models.ImageField(
            upload_to="courses/%Y/%m",
            verbose_name=u"封面图",
            max_length=100)
        # 保存点击量,点进页面就算
        click_nums = models.IntegerField(default=0, verbose_name=u"点击数")
        add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加时间")
    
        class Meta:
            verbose_name = u"课程"
            verbose_name_plural = verbose_name
    
    
    # 章节
    class Lesson(models.Model):
        # 因为一个课程对应很多章节。所以在章节表中将课程设置为外键。
        # 作为一个字段来让我们可以知道这个章节对应那个课程
        course = models.ForeignKey(Course, verbose_name=u"课程", on_delete=models.CASCADE)
        name = models.CharField(max_length=100, verbose_name=u"章节名")
        add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加时间")
    
        class Meta:
            verbose_name = u"章节"
            verbose_name_plural = verbose_name
    
    
    # 每章视频
    class Video(models.Model):
        # 因为一个章节对应很多视频。所以在视频表中将章节设置为外键。
        # 作为一个字段来存储让我们可以知道这个视频对应哪个章节.
        lesson = models.ForeignKey(Lesson, verbose_name=u"章节", on_delete=models.CASCADE)
        name = models.CharField(max_length=100, verbose_name=u"视频名")
        add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加时间")
    
        class Meta:
            verbose_name = u"视频"
            verbose_name_plural = verbose_name
    
    
    # 课程资源
    class CourseResource(models.Model):
        # 因为一个课程对应很多资源。所以在课程资源表中将课程设置为外键。
        # 作为一个字段来让我们可以知道这个资源对应那个课程
        course = models.ForeignKey(Course, verbose_name=u"课程", on_delete=models.CASCADE)
        name = models.CharField(max_length=100, verbose_name=u"名称")
        # 这里定义成文件类型的field,后台管理系统中会直接有上传的按钮。
        # FileField也是一个字符串类型,要指定最大长度。
        download = models.FileField(
            upload_to="course/resource/%Y/%m",
            verbose_name=u"资源文件",
            max_length=100)
        add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加时间")
    
        class Meta:
            verbose_name = u"课程资源"
            verbose_name_plural = verbose_name
    

    organization modesl.py设计

    from datetime import datetime
    
    from django.db import models
    
    # Create your models here.
    
    
    # 城市字典
    class CityDict(models.Model):
        name = models.CharField(max_length=20, verbose_name=u"城市")
        # 城市描述:备用不一定展示出来
        desc = models.CharField(max_length=200, verbose_name=u"描述")
        add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加时间")
    
        class Meta:
            verbose_name = u"城市"
            verbose_name_plural = verbose_name
    
    
    # 课程机构
    class CourseOrg(models.Model):
        name = models.CharField(max_length=50, verbose_name=u"机构名称")
        # 机构描述,后面会替换为富文本展示
        desc = models.TextField(verbose_name=u"机构描述")
        click_nums = models.IntegerField(default=0, verbose_name=u"点击数")
        fav_nums = models.IntegerField(default=0, verbose_name=u"收藏数")
        image = models.ImageField(
            upload_to="org/%Y/%m",
            verbose_name=u"封面图",
            max_length=100)
        address = models.CharField(max_length=150, verbose_name=u"机构地址")
        # 一个城市可以有很多课程机构,通过将city设置外键,变成课程机构的一个字段
        # 可以让我们通过机构找到城市
        city = models.ForeignKey(CityDict, verbose_name=u"所在城市", on_delete=models.CASCADE)
        add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加时间")
    
        class Meta:
            verbose_name = u"课程机构"
            verbose_name_plural = verbose_name
    
    
    # 讲师
    class Teacher(models.Model):
        # 一个机构会有很多老师,所以我们在讲师表添加外键并把课程机构名称保存下来
        # 可以使我们通过讲师找到对应的机构
        org = models.ForeignKey(CourseOrg, verbose_name=u"所属机构", on_delete=models.CASCADE)
        name = models.CharField(max_length=50, verbose_name=u"教师名称")
        work_years = models.IntegerField(default=0, verbose_name=u"工作年限")
        work_company = models.CharField(max_length=50, verbose_name=u"就职公司")
        work_position = models.CharField(max_length=50, verbose_name=u"公司职位")
        points = models.CharField(max_length=50, verbose_name=u"教学特点")
        click_nums = models.IntegerField(default=0, verbose_name=u"点击数")
        fav_nums = models.IntegerField(default=0, verbose_name=u"收藏数")
        add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加时间")
    
        class Meta:
            verbose_name = u"教师"
            verbose_name_plural = verbose_name
    

    operation models.py设计

    from datetime import datetime
    
    # 引入我们CourseComments所需要的外键models
    from django.db import models
    
    from users.models import UserProfile
    from course.models import Course
    
    # 用户我要学习表单
    class UserAsk(models.Model):
        name = models.CharField(max_length=20, verbose_name=u"姓名")
        mobile = models.CharField(max_length=11, verbose_name=u"手机")
        course_name = models.CharField(max_length=50, verbose_name=u"课程名")
        add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加时间")
    
        class Meta:
            verbose_name = u"用户咨询"
            verbose_name_plural = verbose_name
    
    
    # 用户对于课程评论
    class CourseComments(models.Model):
    
        # 会涉及两个外键: 1. 用户, 2. 课程。import进来
        course = models.ForeignKey(Course, verbose_name=u"课程", on_delete=models.CASCADE)
        user = models.ForeignKey(UserProfile, verbose_name=u"用户", on_delete=models.CASCADE)
        comments = models.CharField(max_length=250, verbose_name=u"评论")
        add_time = models.DateTimeField(default=datetime.now, verbose_name=u"评论时间")
    
        class Meta:
            verbose_name = u"课程评论"
            verbose_name_plural = verbose_name
    
    
    # 用户对于课程,机构,讲师的收藏
    class UserFavorite(models.Model):
        # 会涉及四个外键。用户,课程,机构,讲师import
        TYPE_CHOICES = (
            (1, u"课程"),
            (2, u"课程机构"),
            (3, u"讲师")
        )
    
        user = models.ForeignKey(UserProfile, verbose_name=u"用户", on_delete=models.CASCADE)
        # course = models.ForeignKey(Course, verbose_name=u"课程")
        # teacher = models.ForeignKey()
        # org = models.ForeignKey()
        # fav_type =
    
        # 机智版
        # 直接保存用户的id.
        fav_id = models.IntegerField(default=0)
        # 表明收藏的是哪种类型。
        fav_type = models.IntegerField(
            choices=TYPE_CHOICES,
            default=1,
            verbose_name=u"收藏类型")
        add_time = models.DateTimeField(default=datetime.now, verbose_name=u"评论时间")
    
        class Meta:
            verbose_name = u"用户收藏"
            verbose_name_plural = verbose_name
    
    
    # 用户消息表
    class UserMessage(models.Model):
            # 因为我们的消息有两种:发给全员和发给某一个用户。
            # 所以如果使用外键,每个消息会对应要有用户。很难实现全员消息。
    
            # 机智版 为0发给所有用户,不为0就是发给用户的id
        user = models.IntegerField(default=0, verbose_name=u"接收用户")
        message = models.CharField(max_length=500, verbose_name=u"消息内容")
    
        # 是否已读: 布尔类型 BooleanField False未读,True表示已读
        has_read = models.BooleanField(default=False, verbose_name=u"是否已读")
        add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加时间")
    
        class Meta:
            verbose_name = u"用户消息"
            verbose_name_plural = verbose_name
    
    
    # 用户课程表
    class UserCourse(models.Model):
        # 会涉及两个外键: 1. 用户, 2. 课程。import进来
        course = models.ForeignKey(Course, verbose_name=u"课程", on_delete=models.CASCADE)
        user = models.ForeignKey(UserProfile, verbose_name=u"用户", on_delete=models.CASCADE)
        add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加时间")
    
        class Meta:
            verbose_name = u"用户课程"
            verbose_name_plural = verbose_name
    

    将models映射到数据库中

    python manage.py makemigrations
    python manage.py migrate
    

    相关文章

      网友评论

        本文标题:Django+Xadmin打造在线教育系统(一)

        本文链接:https://www.haomeiwen.com/subject/zbsdnftx.html