model设计

Django-APP设计

Django的开发是基于App的

Django app设计:

User -- 用户管理

Course -- 课程管理

Organization -- 机构和教师管理

Operation -- 用户操作管理

新建项目

Setting中配置数据库

Navicat建立对应数据库

自定义userprofile

生成user

startapp users

在model中设计user表:Django本身的user数据库中定义了一些字段。默认的Django的user表示不符合我们的使用需求的,因而在user的model中定义UserProfile类,用来继承Django原有的用来定义user表的类AbstractUser

model当中定义一个类,对应生成数据库中的一张表

 user/model.py

from django.contrib.auth.models import AbstractUser

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,
        verbose_name=u"电话")
    # 头像 指定用户上传头像的目录,默认使用default.png
    image = models.ImageField(
        upload_to="image/%Y/%m",            
        default=u"image/default.png",
        max_length=100,
        verbose_name=u"头像"
    )

    # meta元信息,即后台栏目名
    class Meta:
        verbose_name = "用户信息"
        verbose_name_plural = verbose_name

    # 重载Unicode方法,打印实例会打印username,username为继承自abstractuser
    def __unicode__(self):
        return self.username


user model.py设计

循环引用问题:分层设计app

解决循环引用问题:user中定义的学习课程course,课程的评论中会保存相应的user,相互引用,造成等待。设计一个App高于这些App的层级operation

EmailVerifyRecord - 邮箱验证码,独立的功能,基本只与user产生联系, 在user中models.py中进行定义

from datetime import datetime

class EmailVerifyRecord(models.Model):
    SEND_CHOICES = (
        ("register", u"注册"),
        ("forget", u"找回密码"),
        ("update_email", 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=20,
        verbose_name=u"验证码类型")
    # 这里的now得去掉(),不去掉会根据编译时间。而不是根据实例化时间。
    send_time = models.DateTimeField(
        default=datetime.now, verbose_name=u"发送时间")

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

    # 重载Unicode方法使后台不再直接显示object
    def __unicode__(self):
        return '{0}({1})'.format(self.code, self.email)

PageBanner - 首页轮播图,相对独立

# 轮播图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

    def __unicode__(self):
        return '{0}(位于第{1}位)'.format(self.title, self.index)

user中设计好了如上三个表

course model.py设计

Course课程信息表:外键有机构、讲师(一个课程对应很多章节、课程资源)

Lesson章节信息表:外键有课程,(一个章节对应很多视频)

Video 视频信息表:外键为章节

CourseResource课程资源表:外键为课程

class Course(models.Model):
    DEGREE_CHOICES = (
        ("cj", u"初级"),
        ("zj", u"中级"),
        ("gj", u"高级")
    )
    course_org = models.ForeignKey(CourseOrg, verbose_name=u"所属机构", null=True, blank=True)
    teacher = models.ForeignKey(Teacher, verbose_name=u"讲师", null=True, blank=True)
    name = models.CharField(max_length=50, verbose_name=u"课程名")
    is_banner = models.BooleanField(default=False, verbose_name=u"是否轮播")
    desc = models.CharField(max_length=300, verbose_name=u"课程描述")
    # TextField允许我们不输入长度。可以输入到无限大。暂时定义为TextFiled,之后更新为富文本
    # 修改imagepath,不能传y m 进来,不能加斜杠是一个相对路径,相对于setting中配置的mediaroot
    detail = UEditorField(verbose_name=u"课程详情", width=600, height=300, imagePath="courses/ueditor/", filePath="courses/ueditor/",default='')
    degree = models.CharField(choices=DEGREE_CHOICES, max_length=2, verbose_name=u"难度")
    # 使用分钟做后台记录(存储最小单位)前台转换
    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"收藏人数")
    category = models.CharField(max_length=20, default=u"", verbose_name=u"课程类别")
    you_need_know = models.CharField(max_length=300, default=u"一颗勤学的心是本课程必要前提",verbose_name=u"课程须知")
    teacher_tell = models.CharField(max_length=300, default=u"按时交作业,不然叫家长",verbose_name=u"老师告诉你")
    tag = models.CharField(max_length=15, verbose_name=u"课程标签", default=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

    def get_zj_nums(self):
        return self.lesson_set.all().count()
    get_zj_nums.short_description = "章节数"

    def go_to(self):
        from django.utils.safestring import mark_safe
        # 如果不mark safe。会对其进行转义
        return  mark_safe("跳转")
    go_to.short_description = "跳转"

    def __unicode__(self):
        return self.name


# 章节
class Lesson(models.Model):
    # 因为一个课程对应很多章节。所以在章节表中将课程设置为外键。
    # 作为一个字段来让我们可以知道这个章节对应那个课程
    course = models.ForeignKey(Course, verbose_name=u"课程")
    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

    def __unicode__(self):
        return '《{0}》课程的章节 >> {1}'.format(self.course, self.name)


# 每章视频
class Video(models.Model):
    # 因为一个章节对应很多视频。所以在视频表中将章节设置为外键。
    # 作为一个字段来存储让我们可以知道这个视频对应哪个章节.
    lesson = models.ForeignKey(Lesson, verbose_name=u"章节")
    name = models.CharField(max_length=100, verbose_name=u"视频名")
    url = models.CharField(max_length=200, default="http://blog.VictoriaJiang.cn/" ,verbose_name=u"访问地址")
    # 使用分钟做后台记录(存储最小单位)前台转换
    learn_times = 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

    def __unicode__(self):
        return '{0}章节的视频 >> {1}'.format(self.lesson,self.name)

# 课程资源
class CourseResource(models.Model):
    # 因为一个课程对应很多资源。所以在课程资源表中将课程设置为外键。
    # 作为一个字段来让我们可以知道这个资源对应那个课程
    course = models.ForeignKey(Course, verbose_name=u"课程")
    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

    def __unicode__(self):
        return '《{0}》课程的资源: {1}'.format(self.course,self.name)

organization model.py设计

新建organization的app,会自动生成model

CityDict 城市信息表

CourseOrg 课程机构信息表:外键城市,一个城市有多个机构,可通过城市查找机构

Teacher 教师信息表:外键机构,一个机构对应多个老师,可根据机构查找老师

organization/model.py

# 城市字典
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

    def __unicode__(self):
        return self.name


# 课程机构
class CourseOrg(models.Model):
    ORG_CHOICES =(
        ("pxjg", u"培训机构"),
        ("gx", u"高校"),
        ("gr", u"个人"),
    )

    name = models.CharField(max_length=50, verbose_name=u"机构名称")
    # 机构描述,后面会替换为富文本展示
    desc = models.TextField(verbose_name=u"机构描述")
    # 机构类别:
    category = models.CharField(max_length=20, choices=ORG_CHOICES, verbose_name=u"机构类别", default="pxjg")
    tag = models.CharField(max_length=10, default=u"国内名校", 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"Logo",
        max_length=100)
    address = models.CharField(max_length=150, verbose_name=u"机构地址")
    # 一个城市可以有很多课程机构,通过将city设置外键,变成课程机构的一个字段
    # 可以让我们通过机构找到城市
    city = models.ForeignKey(CityDict, verbose_name=u"所在城市")
    # 当学生点击学习课程,找到所属机构,学习人数加1
    students = models.IntegerField(default=0, verbose_name=u"学习人数")
    # 当发布课程就加1
    course_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

    def __unicode__(self):
        return "课程机构: {0}".format(self.name)


# 讲师
class Teacher(models.Model):
    # 一个机构会有很多老师,所以我们在讲师表添加外键并把课程机构名称保存下来
    # 可以使我们通过讲师找到对应的机构
    org = models.ForeignKey(CourseOrg, verbose_name=u"所属机构")
    image = models.ImageField(
        default = '',
        upload_to = "teacher/%Y/%m",
        verbose_name = u"头像",
        max_length = 100)
    name = models.CharField(max_length=50, verbose_name=u"教师名称")
    work_years = models.IntegerField(default=0, verbose_name=u"工作年限")
    age = models.IntegerField(default=18, 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

    def __unicode__(self):
        return "教师: {0}".format(self.name)

operation model设计

用户咨询表:用户来提交我要学习的需求

用户评论:外键课程、用户

用户收藏

用户消息

用户学习课程:外键课程、用户

from users.models import UserProfile
from courses.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

    def __unicode__(self):
        return '用户: {0} 手机号: {1}'.format(self.name,self.mobile)


# 用户对于课程评论
class CourseComments(models.Model):

    # 会涉及两个外键: 1. 用户, 2. 课程。import进来
    course = models.ForeignKey(Course, verbose_name=u"课程")
    user = models.ForeignKey(UserProfile, verbose_name=u"用户")
    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

    def __unicode__(self):
        return '用户({0})对于《{1}》 评论 :'.format(self.user, self.course)


# 用户对于课程,机构,讲师的收藏
class UserFavorite(models.Model):
    # 会涉及四个外键。用户,课程,机构,讲师import
    TYPE_CHOICES = (
        (1, u"课程"),
        (2, u"课程机构"),
        (3, u"讲师")
    )

    user = models.ForeignKey(UserProfile, verbose_name=u"用户")
    # 直接保存用户的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

    def __unicode__(self):
        return '用户({0})收藏了{1} '.format(self.user, self.fav_type)


# 用户消息表
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

    def __unicode__(self):
        return '用户({0})接收了{1} '.format(self.user, self.message)


# 用户课程表
class UserCourse(models.Model):
    # 会涉及两个外键: 1. 用户, 2. 课程。import进来
    course = models.ForeignKey(Course, verbose_name=u"课程")
    user = models.ForeignKey(UserProfile, verbose_name=u"用户")
    add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加时间")

    class Meta:
        verbose_name = u"用户课程"
        verbose_name_plural = verbose_name

    def __unicode__(self):
        return '用户({0})学习了{1} '.format(self.user, self.course)

最后注意在setting中对app进行注册

 

你可能感兴趣的:(Django项目)