1. 程式人生 > >Django+xadmin打造線上教育平臺(一)

Django+xadmin打造線上教育平臺(一)

目錄

程式碼

線上演示

 一、前言

開發環境:

    python:  3.6.4

    Django: 2.0.2

後臺管理:xadmin

1.1.專案介紹

系統概括:

  • 系統具有完整的使用者登入註冊以及找回密碼功能,擁有完整個人中心。
  • 個人中心: 修改頭像,修改密碼,修改郵箱,可以看到我的課程以及我的收藏。可以刪除收藏,我的訊息。
  • 導航欄: 公開課,授課講師,授課機構,全域性搜尋。
  • 點選公開課–> 課程列表,排序-搜尋。熱門課程推薦,課程的分頁。
  • 點選課程–> 課程詳情頁中對課程進行收藏,取消收藏。富文字展示課程內容。
  • 點選開始學習
    –> 課程的章節資訊,課程的評論資訊。課程資源的下載連結。
  • 點選授課講師–>授課講師列表頁,對講師進行人氣排序以及分頁,右邊有講師排行榜。
  • 點選講師的詳情頁面–> 對講師進行收藏和分享,以及講師的全部課程。
  • 導航欄: 授課機構有分頁,排序篩選功能。
  • 機構列表頁右側有快速提交我要學習的表單。
  • 點選機構–> 左側:機構首頁,機構課程,機構介紹,機構講師。
  • 後臺管理系統可以切換主題。左側每一個功能都有列表顯示, 增刪改查,篩選功能。
  • 課程列表頁可以對不同欄位進行排序。選擇多條記錄進行刪除操作。
  • 課程列表頁:過濾器->選擇欄位範圍等,搜尋,匯出csv,xml,json。
  • 課程新增頁面上傳圖片,富文字的編輯。時間選擇,新增章節,新增課程資源。
  • 日誌記錄:記錄後臺人員的操作

1.2.建立工程

建立工程

django-admin startproject MxOnline

然後開始專案的開發

二、models設計

 專案的開發都是從models設計開始,後臺的管理和前端的渲染無非就是對資料庫的增刪改查,所以models設計的好壞對整個專案的開發起著至關重要的因素。

下面是我畫的圖,可以很直觀的看出來我們需要的models。

放大顯示:

 

建立四個app

python manage.py startapp users

python manage.py startapp course

python manage.py startapp organization

python manage.py startapp operation

然後分別設計每個app的models

2.1.users 使用者

自定義userProfile

 系統自動生成的user表如下:

  • id: 主鍵, password 密碼, last_login Django自動記錄使用者最後登入時間,。
  • is_superuser 表明使用者是否是超級使用者(後臺管理會用到)。
  • username 使用者名稱欄位不要隨便改動, email 郵箱,
  • is_staff 表示是否是員工(後臺管理會用到)。
  • is_active 使用者是否是啟用狀態, date_joined 註冊時間。
我們要擴充套件user表,新增需要的欄位

個人中心頁面資訊:

users/models.py新增程式碼:

# users/models.py

from django.db import models
from django.contrib.auth.models import AbstractUser

class UserProfile(AbstractUser):

    gender_choices = (
        ('male',''),
        ('female','')
    )

    nick_name = models.CharField('暱稱',max_length=50,default='')
    birthday = models.DateField('生日',null=True,blank=True)
    gender = models.CharField('性別',max_length=10,choices=gender_choices,default='female')
    adress = models.CharField('地址',max_length=100,default='')
    mobile = models.CharField('手機號',max_length=11,null=True,blank=True)
    image = models.ImageField(upload_to='image/%Y%m',default='image/default.png',max_length=100)

    class Meta:
        verbose_name = '使用者資訊'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.username

然後做下面的一些設定

因為Image欄位需要用到pillow所以需要安裝該庫

pip install pillow

註冊app

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'users'
]

過載AUTH_USER_MODEL

AUTH_USER_MODEL = 'users.UserProfile'

設計資料庫為Mysql

# DATABASES = {
#     'default': {
#         'ENGINE': 'django.db.backends.sqlite3',
#         'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
#     }
# }

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mxonline',        #資料庫名字
        'USER': 'root',          #賬號
        'PASSWORD': '123456',      #密碼
        'HOST': '127.0.0.1',    #IP
        'PORT': '3306',                   #
    }
}

init.py裡面匯入pymysql模組

# user/__init__.py

import pymysql
pymysql.install_as_MySQLdb()

遷移資料庫

python manage.py makemigrations

python manage.py migrate

user中還需要新增的表(這些功能比較獨立):

  • EmailVerifyRecord - 郵箱驗證碼
  • Banner - 輪播圖

EmailVerifyRecord   驗證碼

程式碼如下:

class EmailVerifyRecord(models.Model):
    send_choices = (
        ('register','註冊'),
        ('forget','找回密碼')
    )

    code = models.CharField('驗證碼',max_length=20)
    email = models.EmailField('郵箱',max_length=50)
    send_type = models.CharField(choices=send_choices,max_length=10)
    send_time = models.DateTimeField(default=datetime.now)

    class Meta:
        verbose_name = '郵箱驗證碼'
        verbose_name_plural = verbose_name

Banner   輪播圖

程式碼如下:

class Banner(models.Model):
    title = models.CharField('標題',max_length=100)
    image = models.ImageField('輪播圖',upload_to='banner/%Y%m',max_length=100)
    url = models.URLField('訪問地址',max_length=200)
    index = models.IntegerField('順序',default=100)
    add_time = models.DateTimeField('新增時間',default=datetime.now)

    class Meta:
        verbose_name = '輪播圖'
        verbose_name_plural = verbose_name

說明:

  image上傳到哪裡

      url是圖片的路徑

      index控制輪播圖的播放順序

這樣users的三張表就建立完了

 寫程式碼要根據PEP8規範

每個class之間要空兩格

2.2.Course 課程

課程app中需要四張表

  • Course  課程表
  • Lesson  章節資訊
  • Video    視訊
  • CourseResource  課程資源

(1)Course  課程表

 程式碼如下:

from datetime import datetime

from django.db import models


class Course(models.Model):
    DEGREE_CHOICES = (
        ("cj", "初級"),
        ("zj", "中級"),
        ("gj", "高階")
    )
    name = models.CharField("課程名",max_length=50)
    desc = models.CharField("課程描述",max_length=300)
    detail = models.TextField("課程詳情")
    degree = models.CharField('難度',choices=DEGREE_CHOICES, max_length=2)
    learn_times = models.IntegerField("學習時長(分鐘數)",default=0)
    students = models.IntegerField("學習人數",default=0)
    fav_nums = models.IntegerField("收藏人數",default=0)
    image = models.ImageField("封面圖",upload_to="courses/%Y/%m",max_length=100)
    click_nums = models.IntegerField("點選數",default=0)
    add_time = models.DateTimeField("新增時間",default=datetime.now,)

    class Meta:
        verbose_name = "課程"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name

(2)Lesson 章節資訊表

 程式碼如下:

class Lesson(models.Model):
    course = models.ForeignKey(Course,verbose_name='課程',on_delete=models.CASCADE)
    name = models.CharField("章節名",max_length=100)
    add_time = models.DateTimeField("新增時間",default=datetime.now)

    class Meta:
        verbose_name = "章節"
        verbose_name_plural = verbose_name

    def __str__(self):
        return '《{0}》課程的章節 >> {1}'.format(self.course, self.name)

(3)Video 視訊

 程式碼如下:

class Video(models.Model):
    lesson = models.ForeignKey(Lesson, verbose_name="章節",on_delete=models.CASCADE)
    name = models.CharField("視訊名",max_length=100)
    add_time = models.DateTimeField("新增時間", default=datetime.now)

    class Meta:
        verbose_name = "視訊"
        verbose_name_plural = verbose_name

(4)CourseResourse  課程資源

class CourseResource(models.Model):
    course = models.ForeignKey(Course, verbose_name="課程",on_delete=models.CASCADE)
    name = models.CharField("名稱",max_length=100)
    download = models.FileField("資原始檔",upload_to="course/resource/%Y/%m",max_length=100)
    add_time = models.DateTimeField("新增時間", default=datetime.now)

    class Meta:
        verbose_name = "課程資源"
        verbose_name_plural = verbose_name

2.3.organization 機構

總共三張表

  • CourseOrg  課程機構基本資訊
  • Teacher       教師基本資訊
  • CityDict        城市資訊

(1)CourseOrg

 程式碼如下:

class CourseOrg(models.Model):
    name = models.CharField('機構名稱',max_length=50)
    desc = models.TextField('機構描述')
    click_nums = models.IntegerField('點選數',default=0)
    fav_nums = models.IntegerField('收藏數',default=0)
    image = models.ImageField('封面圖',upload_to='org/%Y%m',max_length=100)
    address = models.CharField('機構地址',max_length=150,)
    city = models.ForeignKey(CityDict,verbose_name='所在城市',on_delete=models.CASCADE)
    add_time = models.DateTimeField(default=datetime.now)

    class Meta:
        verbose_name = '課程機構'
        verbose_name_plural = verbose_name

(2)CityDict

 程式碼如下:

class CityDict(models.Model):
    name = models.CharField('城市',max_length=20)
    desc = models.CharField('描述',max_length=200)
    add_time = models.DateTimeField(default=datetime.now)

    class Meta:
        verbose_name = '城市'
        verbose_name_plural= verbose_name

(3)Teacher

 程式碼如下:

class Teacher(models.Model):
    org = models.ForeignKey(CourseOrg,verbose_name='所屬機構',on_delete=models.CASCADE)
    name = models.CharField('教師名',max_length=50)
    work_years = models.IntegerField('工作年限',default=0)
    work_company = models.CharField('就職公司',max_length=50)
    work_position = models.CharField('公司職位',max_length=50)
    points = models.CharField('教學特點',max_length=50)
    click_nums = models.IntegerField('點選數',default=0)
    fav_nums = models.IntegerField('收藏數',default=0)
    add_time = models.DateTimeField(default=datetime.now)

    class Meta:
        verbose_name = '教師'
        verbose_name_plural = verbose_name

    def __str__(self):
        return "[{0}]的教師: {1}".format(self.org, self.name)

2.4.operation

總共五張表

  • UseAsk 使用者諮詢
  • UserMessage  使用者訊息表
  • CourseComments 使用者評論
  • UserCourse 使用者學習的課程
  • UserFavorite 使用者收藏

(1)UserAsk

 程式碼如下:

class UserAsk(models.Model):
    name = models.CharField('姓名',max_length=20)
    mobile = models.CharField('手機',max_length=11)
    course_name = models.CharField('課程名',max_length=50)
    add_time = models.DateTimeField('新增時間',default=datetime.now)

    class Meta:
        verbose_name = '使用者諮詢'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name

(2)UserMessage

user欄位,預設0代表訊息是發給所有使用者,而不是某個單獨的使用者;可以通過user.id發給特定使用者訊息

class UserMessage(models.Model):
    user = models.IntegerField('接受使用者',default=0)
    message = models.CharField('訊息內容',max_length=500)
    has_read = models.BooleanField('是否已讀',default=False)
    add_time = models.DateTimeField('新增時間', default=datetime.now)

    class Meta:
        verbose_name = '使用者訊息'
        verbose_name_plural = verbose_name

(3)CourseComments

程式碼如下:

class CourseComments(models.Model):
    user = models.ForeignKey(UserProfile,verbose_name='使用者',on_delete=models.CASCADE)
    course = models.ForeignKey(Course,verbose_name='課程',on_delete=models.CASCADE)
    comments = models.CharField('評論',max_length=200)
    add_time = models.DateTimeField('新增時間', default=datetime.now)

    class Meta:
        verbose_name = '課程評論'
        verbose_name_plural = verbose_name

(4)UserCourse

 程式碼如下:

class UserCourse(models.Model):
    user = models.ForeignKey(UserProfile,verbose_name='使用者',on_delete=models.CASCADE)
    course = models.ForeignKey(Course,verbose_name='課程',on_delete=models.CASCADE)
    add_time = models.DateTimeField('新增時間', default=datetime.now)

    class Meta:
        verbose_name = '使用者課程'
        verbose_name_plural = verbose_name

(5)UserFavorite

 程式碼如下:

class UserFavorite(models.Model):
    FAV_TYPE = (
        (1,'課程'),
        (2,'課程機構'),
        (3,'講師')
    )

    user = models.ForeignKey(UserProfile,verbose_name='使用者',on_delete=models.CASCADE)
    fav_id = models.IntegerField('資料id',default=0)
    fav_type = models.IntegerField(verbose_name='收藏型別',choices=FAV_TYPE,default=1)
    add_time = models.DateTimeField('新增時間', default=datetime.now)

    class Meta:
        verbose_name = '使用者收藏'
        verbose_name_plural = verbose_name

 上面所有models的完整程式碼如下:

# users/models.py

from datetime import datetime

from django.db import models
from django.contrib.auth.models import AbstractUser

class UserProfile(AbstractUser):

    gender_choices = (
        ('male',''),
        ('female','')
    )

    nick_name = models.CharField('暱稱',max_length=50,default='')
    birthday = models.DateField('生日',null=True,blank=True)
    gender = models.CharField('性別',max_length=10,choices=gender_choices,default='female')
    adress = models.CharField('地址',max_length=100,default='')
    mobile = models.CharField('手機號',max_length=11,null=True,blank=True)
    image = models.ImageField(upload_to='image/%Y%m',default='image/default.png',max_length=100)

    class Meta:
        verbose_name = '使用者資訊'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.username


class EmailVerifyRecord(models.Model):
    send_choices = (
        ('register','註冊'),
        ('forget','找回密碼')
    )

    code = models.CharField('驗證碼',max_length=20)
    email = models.EmailField('郵箱',max_length=50)
    send_type = models.CharField(choices=send_choices,max_length=10)
    send_time = models.DateTimeField(default=datetime.now)

    class Meta:
        verbose_name = '郵箱驗證碼'
        verbose_name_plural = verbose_name


class Banner(models.Model):
    title = models.CharField('標題',max_length=100)
    image = models.ImageField('輪播圖',upload_to='banner/%Y%m',max_length=100)
    url = models.URLField('訪問地址',max_length=200)
    index = models.IntegerField('順序',default=100)
    add_time = models.DateTimeField('新增時間',default=datetime.now)

    class Meta:
        verbose_name = '輪播圖'
        verbose_name_plural = verbose_name
users/models.py
# course/models.py

from datetime import datetime

from django.db import models


class Course(models.Model):
    DEGREE_CHOICES = (
        ("cj", "初級"),
        ("zj", "中級"),
        ("gj", "高階")
    )
    name = models.CharField("課程名",max_length=50)
    desc = models.CharField("課程描述",max_length=300)
    detail = models.TextField("課程詳情")
    degree = models.CharField('難度',choices=DEGREE_CHOICES, max_length=2)
    learn_times = models.IntegerField("學習時長(分鐘數)",default=0)
    students = models.IntegerField("學習人數",default=0)
    fav_nums = models.IntegerField("收藏人數",default=0)
    image = models.ImageField("封面圖",upload_to="courses/%Y/%m",max_length=100)
    click_nums = models.IntegerField("點選數",default=0)
    add_time = models.DateTimeField("新增時間",default=datetime.now,)

    class Meta:
        verbose_name = "課程"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name

class Lesson(models.Model):
    course = models.ForeignKey(Course,verbose_name='課程',on_delete=models.CASCADE)
    name = models.CharField("章節名",max_length=100)
    add_time = models.DateTimeField("新增時間",default=datetime.now)

    class Meta:
        verbose_name = "章節"
        verbose_name_plural = verbose_name

    def __str__(self):
        return '《{0}》課程的章節 >> {1}'.format(self.course, self.name)

class Video(models.Model):
    lesson = models.ForeignKey(Lesson, verbose_name="章節",on_delete=models.CASCADE)
    name = models.CharField("視訊名",max_length=100)
    add_time = models.DateTimeField("新增時間", default=datetime.now)

    class Meta:
        verbose_name = "視訊"
        verbose_name_plural = verbose_name


class CourseResource(models.Model):
    course = models.ForeignKey(Course, verbose_name="課程",on_delete=models.CASCADE)
    name = models.CharField("名稱",max_length=100)
    download = models.FileField("資原始檔",upload_to="course/resource/%Y/%m",max_length=100)
    add_time = models.DateTimeField("新增時間", default=datetime.now)

    class Meta:
        verbose_name = "課程資源"
        verbose_name_plural = verbose_name
course/models.py
# operation/models.py

from datetime import datetime

from django.db import models

from course.models import Course
from users.models import UserProfile


class UserAsk(models.Model):
    name = models.CharField('姓名',max_length=20)
    mobile = models.CharField('手機',max_length=11)
    course_name = models.CharField('課程名',max_length=50)
    add_time = models.DateTimeField('新增時間',default=datetime.now)

    class Meta:
        verbose_name = '使用者諮詢'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name


class CourseComments(models.Model):
    user = models.ForeignKey(UserProfile,verbose_name='使用者',on_delete=models.CASCADE)
    course = models.ForeignKey(Course,verbose_name='課程',on_delete=models.CASCADE)
    comments = models.CharField('評論',max_length=200)
    add_time = models.DateTimeField('新增時間', default=datetime.now)

    class Meta:
        verbose_name = '課程評論'
        verbose_name_plural = verbose_name


class UserFavorite(models.Model):
    FAV_TYPE = (
        (1,'課程'),
        (2,'課程機構'),
        (3,'講師')
    )

    user = models.ForeignKey(UserProfile,verbose_name='使用者',on_delete=