IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> Django项目_课程商城_开发学习日志NO.2_新建app和orm映射数据库 -> 正文阅读

[Python知识库]Django项目_课程商城_开发学习日志NO.2_新建app和orm映射数据库

一、需求分析

商城系统需要的app如下:

在这里插入图片描述

分别是课程、操作、机构、用户的app设计

二、新建app和配置app

1.新建

在run manage.py Task中使用startapp xxx来新建

无pycharm用以下命令创建:python manage.py startapp app名字

如下:

manage.py@day8_8 > startapp users

2.配置

创建后需要在settings里的INSTALLED_APPS里面配置,配置格式:app名字.apps.app名字Config

如下:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'apps.users.apps.UsersConfig',
    'apps.courses.apps.CoursesConfig',
    'apps.operations.apps.OperationsConfig',
    'apps.organizations.apps.OrganizationsConfig',
]

配置成功

三、数据库设计

1.基本知识


数据库每次修改都需要迁移,两个语句:
python manage.py makemigrations
python manage.py migrate


无工具查看dbsqlite3库时用语句:
py manage.py sqlmigrate app名字 0001


具体就是:
1.编辑 models.py 文件,改变模型。
2.运行 python manage.py makemigrations 为模型的改变生成迁移文件
3.运行 python manage.py migrate 来应用数据库迁移


???
至关重要,需要思考
设计表的原则或注意点

  1. 注意表的分层设计,即只上层调用下层,避免了表间循环引用造成的错误。
  2. 注意表间实体的关系,即实体1 <关系> 实体2,分清是多对多还是一对多。
  3. 确定实体的具体字段、字段类型、是否必填等

2.最重要的用户表的重载

用户表是第一张需要设计的表,即auth_user这张表

这张表是django自带的

初始情况如下:
在这里插入图片描述
很多数据都是可用的,但是我们任然需要很多额外的属性,可以对该表进行重载

apps.users.models.py这个app下的model模块内:

##重新定义用户表必须引用这个类
from django.contrib.auth.models import AbstractUser

class UserProfile(AbstractUser):
    nick_name = models.CharField(max_length=20 ,verbose_name='昵称', default="")
    birthday = models.DateField(verbose_name='生日',null=True,blank=True)
    gender = models.CharField(verbose_name='性别',choices=(('male','男'),('famale','女')),max_length=6)
    address = models.CharField(verbose_name='地址',max_length=100,default='')
    mobile = models.CharField(verbose_name='手机号码',max_length=11)#unique表示不能重复
    image = models.ImageField(upload_to="head_image/%Y/%m",default='default.jpg',verbose_name='用户头像')

	#Meta类反映表的基本信息
    class Meta:
        verbose_name = '用户信息'
        verbose_name_plural = verbose_name
    #返回字段的函数
    def __str__(self):
        if self.nick_name:
            return self.nick_name
        else:
            return self.username

仅用户类需要:之后需要在setting中配置好AUTH_USER_MODEL = 'users.UserProfile',否则失效。

迁移后,可以看到原来的auth_user表变为了users_userprofile

至此用户表重载成功!!!

注意
from django.contrib.auth.models import AbstractUser #重新定义用户表必须引用这个类

#Meta类反映表的基本信息
class Meta:
        verbose_name = '用户信息' 
        verbose_name_plural = verbose_name 
        """
        本来后台显示是'user'
        两句之后显示就是'用户信息'了
        """
        db_table = "user" #表名改为user

"""
返回字段的函数
后台添加、修改等等成功时就会返回“具体name成功修改的字样”
而不是奇奇怪怪的返回
"""
    def __str__(self):
        if self.nick_name:
            return self.nick_name
        else:
            return self.username

3.model中常用设置

①如果可以为空的语句,使用null=True,blank=True即可,否则不能为空,为必填字段,但可以给定一个默认值default=’’


choices=((‘male’,‘男’),(‘famale’,‘女’)) :选择按钮
max_length=100:最大长度
verbose_name=‘昵称’ :显示名
help_text:提示信息
unique = True:表示不能重复
upload_to = ‘路径’ :文件上传保存的路径
primary_key=True :设置为主键

常用的models.xxxField:

CharField、IntegerField、DateTimeField、DateField、ImageField、BooleanField 等。

4.公共类的设置

?
有一个公共功能时,可以在任意model.py中先写一个类,然后其他都继承它

from django.db import models
from datetime import datetime

class BaseModel(models.Model):
    add_time = models.DateTimeField(default=datetime.now,verbose_name='添加时间')
	
	#表示是抽象类,本身只提供调用的功能
    class Meta:
        abstract = True

这是一个有”添加时间“属性的公共类,其他类都可以调用继承它来获得”添加时间“这个属性。注意Meta中abstract = True的设置,只有这样才不会生成多余的表。

5.课程表的设计(course)

需求分析:课程表需要有 课程、 章节、 视频 、课程资源四个实体

PS:含外键的使用

基础ORM映射是和User表是一样的
实现如下:

from django.db import models

# Create your models here.
from apps.users.models import BaseModel
from apps.organizations.models import Teacher

class Course(BaseModel):
    teacher = models.ForeignKey(Teacher,on_delete=models.CASCADE,verbose_name='讲师')
    name = models.CharField(verbose_name='课程名',max_length=50)
    desc = models.CharField(verbose_name='课程描述',max_length=300)
    learn_times = models.IntegerField(default=0 , verbose_name='学习时长')
    degree = models.CharField(verbose_name='难度',choices=(('jd','简单'),('pt','普通'),('kn','困难')),max_length=2)
    students = models.IntegerField(verbose_name='学生人数',default=0)
    fav_nums = models.IntegerField(verbose_name='粉丝人数',default=0)
    click_nums = models.IntegerField(verbose_name='点击数',default=0)
    category = models.CharField(default=u'后端开发',verbose_name='课程类别',max_length=20)
    tag = models.CharField(default='',verbose_name='课程标签',max_length=10)
    youneed_know = models.CharField(default='',max_length=200,verbose_name='课程须知')
    teacher_tell = models.CharField(default='',max_length=200,verbose_name='老实告诉你')


    detail = models.TextField(verbose_name='课程详情')
    image = models.ImageField(upload_to='courses/%Y/%m',verbose_name='封面图',max_length=100)


    class Meta:
        verbose_name = '课程信息'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name

class Lesson(BaseModel):
    course = models.ForeignKey(Course , on_delete=models.CASCADE) #对应Course的外键,On_delete是关键点
    name = models.CharField(max_length=20,verbose_name='章节名')
    learn_times = models.IntegerField(default=0 ,verbose_name='学习时长(分钟数)')
    class Meta:
        verbose_name = '课程章节'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name

class Vedio(BaseModel):
    lesson = models.ForeignKey(Lesson , on_delete= models.CASCADE)
    name = models.CharField(verbose_name='视频名',max_length=20)
    learn_times = models.IntegerField(default=0,verbose_name='学习时长')
    url = models.FileField(max_length=200,verbose_name='访问地址')

    class Meta:
        verbose_name = '视频'
        verbose_name_plural = verbose_name
    def __str__(self):
        return self.name

class CourseResource(BaseModel):
    course = models.ForeignKey(Course , on_delete=models.CASCADE,verbose_name='课程名称')
    name = models.CharField(max_length=100,verbose_name='名称')
    file = models.FileField(upload_to='course/resource%Y%m',max_length=200,verbose_name='下载地址')
    class Meta:
        verbose_name = '课程资源'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name

分析
from apps.users.models import BaseModel导入公共类用于继承。
可以看到后面每个类都继承了BaseModel,即拥有了add_time这个属性(详情看上面),自己类的下面就写自己需要的属性即可。

②该表是课程表,结构为:
课程–多个章节、多个课程资源推荐
章节–多个视频
所以得出结论:课程作为章节和课程资源的外键,章节作为视频的外键,可以看到,正好代码也是如此完成。

③知识点:外键的设置
Lesson类(章节类)为例:

class Lesson(BaseModel):
    course = models.ForeignKey(Course , on_delete=models.CASCADE)

models.ForeignKey 是用于设置外键
Course 是以Course类为外键
on_delete=models.CASCADE on_delete意义是该外键被删除后,依赖于此外键的这个类的数据怎么办。models.CASCADE意思是对应外键被删,即删除此数据。models.SET_NULL是数据置为null。

6.课程机构表的设计(organaziton)

需求分析:课程机构表需要有 所在城市、 课程机构、 机构教师 三个实体

课程机构以城市为外键
教师以机构为外键

from django.db import models

# Create your models here.
from apps.users.models import BaseModel


class City(BaseModel):
    name = models.CharField(max_length=20, verbose_name="城市名")
    desc = models.CharField(max_length=200, verbose_name="描述")

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

    def __str__(self):
        return self.name

class CourseOrg(BaseModel):
    name = models.CharField(max_length=50, verbose_name="机构名称")
    desc = models.TextField(verbose_name="描述")
    tag = models.CharField(default="全国知名", max_length=10, verbose_name="机构标签")
    category = models.CharField(default="pxjg", verbose_name="机构类别", max_length=4,
                                choices=(("pxjg", "培训机构"), ("gr", "个人"), ("gx", "高校")))
    click_nums = models.IntegerField(default=0, verbose_name="点击数")
    fav_nums = models.IntegerField(default=0, verbose_name="收藏数")
    image = models.ImageField(upload_to="org/%Y/%m", verbose_name="logo", max_length=100)
    address = models.CharField(max_length=150, verbose_name="机构地址")
    students = models.IntegerField(default=0, verbose_name="学习人数")
    course_nums = models.IntegerField(default=0, verbose_name="课程数")

    is_auth = models.BooleanField(default=False, verbose_name="是否认证")
    is_gold = models.BooleanField(default=False, verbose_name="是否金牌")

    city = models.ForeignKey(City, on_delete=models.CASCADE, verbose_name="所在城市")

    class Meta:
        verbose_name = "课程机构"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name

class Teacher(BaseModel):
    org = models.ForeignKey(CourseOrg, on_delete=models.CASCADE, verbose_name="所属机构")
    name = models.CharField(max_length=50, verbose_name="教师名")
    work_years = models.IntegerField(default=0, verbose_name="工作年限")
    work_company = models.CharField(max_length=50, verbose_name="就职公司")
    work_position = models.CharField(max_length=50, verbose_name="公司职位")
    points = models.CharField(max_length=50, verbose_name="教学特点")
    click_nums = models.IntegerField(default=0, verbose_name="点击数")
    fav_nums = models.IntegerField(default=0, verbose_name="收藏数")
    age = models.IntegerField(default=18, verbose_name="年龄")
    image = models.ImageField(upload_to="teacher/%Y/%m", verbose_name="头像", max_length=100)

    class Meta:
        verbose_name = "教师"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name

7.用户操作表的设计(operation)

需求分析:用户操作表需要有 用户咨询、 课程评论、 用户消息、 用户课程 四个实体

用户咨询不需要登陆即可使用,所以无外键
课程评论、 用户消息、 用户课程都需要用户登录后使用,所以都以用户为外键。

值得注意的是
课程评论需要两个外键,一个是用户的评论,一个是课程下面的评论。

from django.db import models

from django.contrib.auth import get_user_model

from apps.users.models import BaseModel
from apps.courses.models import Course

UserProfile = get_user_model()

class UserAsk(BaseModel):
    name = models.CharField(max_length=20, verbose_name="姓名")
    mobile = models.CharField(max_length=11, verbose_name="手机")
    course_name = models.CharField(max_length=50, verbose_name="课程名")

    class Meta:
        verbose_name = "用户咨询"
        verbose_name_plural = verbose_name
    def __str__(self):
        return "{name}_{course_name}({mobile})".format(name=self.name,course_name=self.course_name,mobile=self.mobile)

class CourseComments(BaseModel):
    user = models.ForeignKey(UserProfile, on_delete=models.CASCADE, verbose_name="用户")
    course = models.ForeignKey(Course, on_delete=models.CASCADE, verbose_name="课程")
    comments = models.CharField(max_length=200, verbose_name="评论内容")

    class Meta:
        verbose_name = "课程评论"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.comments

class UserFavorite(BaseModel):
    user = models.ForeignKey(UserProfile, on_delete=models.CASCADE, verbose_name="用户")
    fav_id = models.IntegerField(verbose_name="数据id")
    fav_type = models.IntegerField(choices=((1,"课程"),(2,"课程机构"),(3,"讲师")), default=1, verbose_name="收藏类型")

    class Meta:
        verbose_name = "用户收藏"
        verbose_name_plural = verbose_name
    def __str__(self):
        return "{user}_{id}".format(user=self.user,id=self.fav_id)

class UserMessage(BaseModel):
    user = models.ForeignKey(UserProfile, on_delete=models.CASCADE, verbose_name="用户")
    message = models.CharField(max_length=200, verbose_name="消息内容")
    has_read = models.BooleanField(default=False, verbose_name="是否已读")

    class Meta:
        verbose_name = "用户消息"
        verbose_name_plural = verbose_name

class UserCourse(BaseModel):
    user = models.ForeignKey(UserProfile, on_delete=models.CASCADE, verbose_name="用户")
    course = models.ForeignKey(Course, on_delete=models.CASCADE, verbose_name="课程")

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

    def __str__(self):
        return self.course.name

注意
问:为什么这里不直接import之前写好的UserProfile这个用户类?

答:有局限性,我们用自己定义的UserProfile,如果后面要用django自带的用户表需要把所以的UserProfile都修改,很麻烦。

解决方法:使用get_user_model方法通过解析setting.py的中的AUTH_USER_MODEL = 'users.UserProfile'可以知道是否覆盖了django自带的用户表,如果有则读取到哪一个类覆盖了原用户表

from django.contrib.auth import get_user_model
#得到用户表并且传递给UserProfile
UserProfile = get_user_model()

后面以用户表为外键时就可以用UserProfile

四、总结

最后经过
python manage.py makemigrations
python manage.py migrate
两条命令就可以生成表了,如图:

在这里插入图片描述
tips:如果是新建的项目,此时报错,直接把所以库都删了重新两步走即可。

最重要的还是:

  1. 注意表的分层设计,即只上层调用下层,避免了表间循环引用造成的错误。
  2. 注意表间实体的关系,即实体1 <关系> 实体2,分清是多对多还是一对多。
  3. 确定实体的具体字段、字段类型、是否必填等

这些都需要在建表时思考

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2021-08-09 10:12:00  更:2021-08-09 10:12:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 14:37:55-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码