一、项目介绍
该项目使用Django+xadmin打造在线教育平台整站,通过该项目的学习可以对Django框架有一个整体的了解,学会使用Django的MVC设计模式,学会使用Django的模板技术来实现前端页面的显示。学习如何就一个项目去合理的进行数据库的设计,以及就前端页面去设计后端接口。学会通过xadmin快速搭建网站的后台管理系统。
项目整体分为四个模块:用户信息相关模块、机构相关模块、课程相关模块、用户操作相关模块。
项目功能概括:
1、首先具有完整的用户登录,邮箱注册以及找回密码功能。
2、拥有完整的个人中心,个人中心可以修改头像、密码、邮箱,可以看到我的课程、我的收藏及我的消息。
3、首页导航栏有公开课、授课讲师、授课机构,顶部还有全局搜索。
4、导航栏点击公开课显示课程的列表、可以对课程进行排序、搜索,还有热门课程的推荐,课程较多可以进行分页。
5、点击具体的课程可以显示课程的详情页面,该页中可以对课程进行收藏、学习,通过富文本展示课程的详细描述信息。
6、点击开始学习,进入课程的学习页面,该页有课程的章节信息、评论信息,可以对课程进行评论,可以将课程资源进行下载。
7、导航栏点击授课讲师,显示所有讲师列表,可以对讲师进行人气排序,讲师过多会进行分页显示,右边有讲师排行榜。
8、点击某一个讲师,进入讲师详情页面,显示讲师的全部课程,可以对该讲师进行收藏和分享。
9、导航栏点击授课机构,进入机构的列表页,可以对机构进行排序和筛选。
10、点击某一个机构,进入机构首页,左侧有导航栏,有机构首页、机构课程、机构介绍、机构讲师。
项目的开发流程:
开发环境的搭建--->model数据库的设计--->xadmin搭建后台管理系统并录入数据--->url设计--->form以及modelform表单设计--->template模板设计--->view实现各功能模块--->常见的网络攻击与防护--->项目上线
开发环境:python3.6.4+django2.0.2
二、项目环境搭建
pycharm新建一个项目,创建django项目,指定项目的虚拟环境,点击确定即可创建好一个django框架项目。
创建好之后,项目的目录结构如下:
现在django项目已经搭建好了,下面就可以开始开发了。
三、model数据库设计
1、创建模块
项目的开发都是从数据库model设计开始的,model设计的好坏对整个项目的开发起着非常重要的因素。
在设计model之前需要先创建好项目的四个app(模块),首先在pycharm的工具栏中找到Tools,点击Run manage.py Task这个选项,启动manage.py文件,用这个文件来创建项目的模块,还可以通过这个文件来迁移数据库,还可以创建后台的管理人员账号。
依次创建四个app:
startapp users(用户相关模块)
startapp course(课程相关模块)
startapp organization(机构相关模块)
startapp operation(用户操作相关模块)
创建完成之后,就可以设计每个app的数据库model了
2、数据库设计
2.1 users用户设计
用户app中需要设计三张表:
UserProfile 用户信息
EmailVerifyRecord 邮箱验证码
Banner 轮播图
通过个人中心页面,可以设计出用户信息相关的model:
我们可以继承Django已经有的一个类AbstractUser,这个类中有用户相关的一些字段信息,继承这个类后可以自定义我们需要的一些字段,如个人中心中的昵称,生日,性别,地址,手机号,头像,确定好之后就可以编写用户信息的model了,在users/models.py编写数据库设计的代码:
1 from django.db import models 2 from django.contrib.auth.models import AbstractUser 3 4 # Create your models here. 5 6 class UserProfile(AbstractUser): 7 GENDER_CHOICES = ( 8 (\'male\', \'男\'), 9 (\'female\', \'女\') 10 ) 11 12 nick_name = models.CharField(\'昵称\', max_length=50, default=\'\') 13 birthday = models.DateField(\'生日\', null=True, blank=True) 14 gender = models.CharField(\'性别\', max_length=10, choices=GENDER_CHOICES, default=\'male\') 15 address = models.CharField(\'地址\', max_length=100, default=\'\') 16 mobile = models.CharField(\'手机号\', max_length=11, null=True, blank=True) 17 image = models.ImageField(\'头像\', upload_to=\'image/%Y%m\', default=\'image/default.png\', max_length=100) 18 19 class Meta: 20 verbose_name = \'用户信息\' 21 verbose_name_plural = verbose_name 22 23 def __str__(self): 24 return self.username
因为image字段需要用到pillow库,所以需要先安装pillow库:pip install pillow
然后将这个app注册到setting.py文件中的INSTALLED_APPS中,然后重载AUTH_USER_MODEL:
1 INSTALLED_APPS = [ 2 \'django.contrib.auth\', 3 \'django.contrib.contenttypes\', 4 \'django.contrib.sessions\', 5 \'django.contrib.messages\', 6 \'django.contrib.staticfiles\', 7 \'users\' 8 ] 9 AUTH_USER_MODEL = \'users.UserProfile\'
然后在setting.py文件中配置数据库:
1 DATABASES = { 2 \'default\': { 3 \'ENGINE\': \'django.db.backends.mysql\', 4 \'NAME\': \'mxonline\', 5 \'USER\': \'root\', 6 \'PASSWORD\': \'python\', 7 \'HOST\': \'127.0.0.1\', 8 \'PORT\': \'3306\' 9 } 10 }
现在就可以迁移数据库了,首先在pycharm的工具栏中找到Tools,点击Run manage.py Task这个选项,启动manage.py文件,用这个文件来执行迁移数据库的命令:
makemigrations
migrate
数据库生成完成。
然后开始设计EmailVerifyRecord表,这个表的字段有验证码、邮箱、发送的类型、发送的时间:
1 class EmailVerifyRecord(models.Model): 2 """邮箱验证码""" 3 SEND_CHOICES = ( 4 (\'register\', \'注册\'), 5 (\'forget\', \'找回密码\') 6 ) 7 8 code = models.CharField(\'验证码\', max_length=20) 9 email = models.EmailField(\'邮箱\', max_length=50) 10 send_type = models.CharField(\'发送类型\', max_length=10, choices=SEND_CHOICES) 11 send_time = models.DateTimeField(\'发送时间\', default=datetime.now) 12 13 class Meta: 14 verbose_name = \'邮箱验证码\' 15 verbose_name_plural = verbose_name
然后开始设计Banner表,这个表的字段有标题、轮播图片、访问地址、播放顺序、添加时间:
1 class Banner(models.Model): 2 """轮播图""" 3 title = models.CharField(\'标题\', max_length=100) 4 image = models.ImageField(\'轮播图\', upload_to=\'banner/%Y%m\', max_length=100) 5 url = models.URLField(\'访问地址\', max_length=200) 6 index = models.IntegerField(\'轮播顺序\', default=100) 7 add_time = models.DateTimeField(\'添加时间\', default=datetime.now) 8 9 class Meta: 10 verbose_name = \'轮播图\' 11 verbose_name_plural = verbose_name
至此,users这个模块的数据库设计完毕,执行迁移数据库的命令生成数据库中的表。
2.2 course课程设计
课程app中需要四张表:
Course 课程信息
Lesson 章节信息
Video 视频信息
CourseResource 课程资源
在course/models.py文件中编写Course课程相关代码:
1 from datetime import datetime 2 3 from django.db import models 4 5 # Create your models here. 6 7 class Course(models.Model): 8 """课程""" 9 DEGREE_CHOICES = ( 10 (\'cj\', \'初级\'), 11 (\'zj\', \'中级\'), 12 (\'gj\', \'高级\') 13 ) 14 15 name = models.CharField(\'课程名\', max_length=50) 16 desc = models.CharField(\'课程描述\', max_length=300) 17 detail = models.TextField(\'课程详情\') 18 degree = models.CharField(\'课程难度\', choices=DEGREE_CHOICES, max_length=2) 19 learn_times = models.IntegerField(\'学习时长(分钟数)\', default=0) 20 students = models.IntegerField(\'学习人数\', default=0) 21 fav_nums = models.IntegerField(\'收藏人数\', default=0) 22 click_nums = models.IntegerField(\'点击数\', default=0) 23 image = models.ImageField(\'封面图\', upload_to=\'courses/%Y/%m\', max_length=100) 24 add_time = models.DateTimeField(\'添加时间\', default=datetime.now) 25 26 class Meta: 27 verbose_name = \'课程\' 28 verbose_name_plural = verbose_name 29 30 def __str__(self): 31 return self.name 32 33 34 class Lesson(models.Model): 35 """章节""" 36 course = models.ForeignKey(Course, verbose_name=\'课程\', on_delete=models.CASCADE) 37 name = models.CharField(\'章节名\', max_length=100) 38 add_time = models.DateTimeField(\'添加时间\', default=datetime.now) 39 40 class Meta: 41 verbose_name = \'章节\' 42 verbose_name_plural = verbose_name 43 44 def __str__(self): 45 return \'《{}》课程的章节:{}\'.format(self.course.name, self.name) 46 47 48 class Video(models.Model): 49 """视频""" 50 lesson = models.ForeignKey(Lesson, verbose_name=\'章节\', on_delete=models.CASCADE) 51 name = models.CharField(\'视频名\', max_length=100) 52 add_time = models.DateTimeField(\'添加时间\', default=datetime.now) 53 54 class Meta: 55 verbose_name = \'视频\' 56 verbose_name_plural = verbose_name 57 58 59 class CourseResourse(models.Model): 60 """课程资源""" 61 course = models.ForeignKey(Course, verbose_name=\'课程\', on_delete=models.CASCADE) 62 name = models.CharField(\'资源名称\', max_length=100) 63 download = models.FileField(\'资源文件\', upload_to=\'course/resource/%Y/%m\', max_length=100) 64 add_time = models.DateTimeField(\'添加时间\', default=datetime.now) 65 66 class Meta: 67 verbose_name = \'课程资源\' 68 verbose_name_plural = verbose_name
完成之后需要将course这个app注册进settings.py文件中的INSTALLED_APPS,注册进入之后,就可以迁移数据库生成数据库中的表了。
2.3 organization机构设计
机构app中需要三张表:
CourseOrg 课程机构基本信息
Teacher 教师基本信息
CityDict 城市信息
在organization/models.py文件中编写organization机构相关代码:
1 from datetime import datetime 2 3 from django.db import models 4 5 # Create your models here. 6 7 class CityDict(models.Model): 8 """城市""" 9 name = models.CharField(\'名称\', max_length=20) 10 desc = models.CharField(\'描述\', max_length=200) 11 add_time = models.DateTimeField(\'添加时间\', default=datetime.now) 12 13 class Meta: 14 verbose_name = \'城市\' 15 verbose_name_plural = verbose_name 16 17 18 class CourseOrg(models.Model): 19 """课程机构""" 20 name = models.CharField(\'机构名称\', max_length=50) 21 desc = models.TextField(\'机构描述\') 22 click_nums = models.IntegerField(\'点击数\', default=0) 23 fav_nums = models.IntegerField(\'收藏数\', default=0) 24 image = models.ImageField(\'封面图\', upload_to=\'org/%Y/%m\', max_length=100) 25 address = models.CharField(\'地址\', max_length=150) 26 city = models.ForeignKey(CityDict, verbose_name=\'所在城市\', on_delete=models.CASCADE) 27 add_time = models.DateTimeField(\'添加时间\', default=datetime.now) 28 29 class Meta: 30 verbose_name = \'课程机构\' 31 verbose_name_plural = verbose_name 32 33 34 class Teacher(models.Model): 35 """机构老师""" 36 org = models.ForeignKey(CourseOrg, verbose_name=\'所属机构\', on_delete=models.CASCADE) 37 name = models.CharField(\'老师名\', max_length=50) 38 work_years =models.IntegerField(\'工作年限\', default=0) 39 work_company = models.CharField(\'就职公司\', max_length=50) 40 work_position = models.CharField(\'工作职位\', max_length=50) 41 points = models.CharField(\'教学特点\', max_length=50) 42 click_nums = models.IntegerField(\'点击数\', default=0) 43 fav_nums = models.IntegerField(\'收藏数\', default=0) 44 add_time = models.DateTimeField(\'添加时间\', default=datetime.now) 45 46 class Meta: 47 verbose_name = \'教师\' 48 verbose_name_plural = verbose_name 49 50 def __str__(self): 51 return \'[{}]机构的教师:{}\'.format(self.org.name, self.name)
完成之后需要将organization这个app注册进settings.py文件中的INSTALLED_APPS,注册进入之后,就可以迁移数据库生成数据库中的表了。
2.4 operation用户操作设计
用户操作app中需要五张表:
UseAsk 用户咨询相关
UserMessage 用户消息相关
CourseComments 用户评论相关
UserCourse 用户学习的课程相关
UserFavorite 用户收藏相关
在operation/models.py文件中编写operation用户操作相关代码:
1 from datetime import datetime 2 3 from django.db import models 4 5 from users.models import UserProfile 6 from course.models import Course 7 8 # Create your models here. 9 10 class UserAsk(models.Model): 11 """用户咨询""" 12 name = models.CharField(\'姓名\', max_length=20) 13 mobile = models.CharField(\'手机\', max_length=11) 14 course_name = models.CharField(\'课程名\', max_length=50) 15 add_time = models.DateTimeField(\'添加时间\', default=datetime.now) 16 17 class Meta: 18 verbose_name = \'用户咨询\' 19 verbose_name_plural = verbose_name 20 21 def __str__(self): 22 return self.name 23 24 25 class UserMessage(models.Model): 26 """用户消息""" 27 user = models.IntegerField(\'接收用户\', default=0) # 默认0代表发送给所有用户,可以通过user.id发送给指定用户 28 message = models.CharField(\'消息内容\', max_length=500) 29 has_read = models.BooleanField(\'是否已读\', default=False) 30 add_time = models.DateTimeField(\'添加时间\', default=datetime.now) 31 32 class Meta: 33 verbose_name = \'用户消息\' 34 verbose_name_plural = verbose_name 35 36 37 class CourseComments(models.Model): 38 """课程评论""" 39 user = models.ForeignKey(UserProfile, verbose_name=\'用户\', on_delete=models.CASCADE) 40 course = models.ForeignKey(Course, verbose_name=\'课程\', on_delete=models.CASCADE) 41 comments = models.CharField(\'评论内容\', max_length=200) 42 add_time = models.DateTimeField(\'添加时间\', default=datetime.now) 43 44 class Meta: 45 verbose_name = \'课程评论\' 46 verbose_name_plural = verbose_name 47 48 49 class UserCourse(models.Model): 50 """用户课程""" 51 user = models.ForeignKey(UserProfile, verbose_name=\'用户\', on_delete=models.CASCADE) 52 course = models.ForeignKey(Course, verbose_name=\'课程\', on_delete=models.CASCADE) 53 add_time = models.DateTimeField(\'添加时间\', default=datetime.now) 54 55 class Meta: 56 verbose_name = \'用户课程\' 57 verbose_name_plural = verbose_name 58 59 60 class UserFavorite(models.Model): 61 """用户收藏""" 62 FAV_CHOICES = ( 63 (1, \'课程\'), 64 (2, \'课程机构\'), 65 (3, \'讲师\'), 66 ) 67 user = models.ForeignKey(UserProfile, verbose_name=\'用户\', on_delete=models.CASCADE) 68 fav_id = models.IntegerField(\'数据id\', default=0) 69 fav_type = models.IntegerField(verbose_name=\'收藏类型\', choices=FAV_CHOICES, default=1) 70 add_time = models.DateTimeField(\'添加时间\', default=datetime.now) 71 72 class Meta: 73 verbose_name = \'用户收藏\' 74 verbose_name_plural = verbose_name
完成之后需要将operation这个app注册进settings.py文件中的INSTALLED_APPS,注册进入之后,就可以迁移数据库生成数据库中的表了。
2.5 模块规范化
为了方便管理,将四个模块放到同一个文件夹中,在项目根目录下新建包apps,把这四个模块全部放进这个包中,注意在拖动的时候不要选择Search for references。
然后将apps这个包右键Mark Directory as,选择Sources Root,让pycharm可以找到这些模块。
但是如果在其他环境部署的时候会报错,需要在settings.py中进行设置。
1 import os 2 import sys 3 4 # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 5 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 6 sys.path.insert(0, os.path.join(BASE_DIR, \'apps\'))
此刻项目的目录结构如下: