【Django】基于PythonWeb的Django框架设计实现天天生鲜系统-3模型创建

2021-08-11 15:50:53 浏览数 (1)

1 ORM 概述

当前项目的开发都是数据库驱动,即分析出项目中所需要存储的数据,然后设计数据表结构,接下来对通过编写 SQL 语句对数据库中的表进行 CURD 操作。

Django 提供了一套针对数据库操作的代码库, 通过该代码库中提供的工具, 我们可以创建查询、生成SQL语句,并且这些SQL无需开发人员自己处理。这样带来的好处是开发人员无需对 SQL 和 关系型数据库有深入的了解就能直接编写自己的查询。

我们把这套库称作 ORM 库, ORM 是对象关系映射, 对象表示的是我们Python中的对象概念, 关系指的是关系型数据库. 通过 ORM 完成 对象和 数据库中的表之前的一一对应关系. 对对象的任何操作就是对表的操作.

另外 ORM 强大的地方,ORM支持多种数据库后端。可非常简单帮助我们切换后端数据库。Django中提供了自己内置的 ORM 库。我们不需要面向数据库编程,而是通过定义模型类,通过对我们的模型类和对象的方法调用,从而完成了对数据库 CRUD 操作。

简言之, ORM 库帮我们封装了对关系型数据库的 CRUD 操作, 我们不需要编写一行 SQL, 即可完成对数据库的操作.

2 数据库配置

打开 ttsx/settings.py 文件, 在该配置文件中默认使用的是 SQLITE 数据库, 原 SQLITE 配置内容如下:

代码语言:javascript复制
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

现配置项目数据库为 MYSQL:

代码语言:javascript复制
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',  # mysql数据库引擎
        'NAME': 'my_ttsx',  # 数据库名字
        'USER': 'root',  # 用户名
        'PASSWORD': 'chuanzhi',  # 密码
        'HOST': 'localhost',  # 主机
        'PORT': '3306'  # 端口
    }
}

配置完成之后, 在 ttsx 目录下的 __init__.py 中增加如下代码:

代码语言:javascript复制
import pymysql
pymysql.install_as_MySQLdb()

一定要保证配置文件中指定的数据库是存在的, 如果不存在需要创建对应数据库. 启动测试服务器, 如果没有报错, 那么表示配置成功.

3 创建模型

在 Django 中一个模型类就对应着数据库中的一张表, 对模型类的任何操作都是对数据库表的操作. 在该项目中, 我们需要对业务进行分析, 然后创建所需要的表.

关于商品展示部分, 我们需要两张数据库表:

  • GoodsCategory 表, 存储商品分类信息.
    • 分类显示名称
    • 分类显示样式
    • 分类显示图片
  • GoodsInfo 表, 存储商品具体信息.
    • 商品名称
    • 商品单位
    • 商品价格
    • 商品图片
    • 商品描述
    • 商品分类

关于购物车部分, 我们也需要两张表:

  • OrderInfo 表, 存储订单基本信息.
    • 订单编号
    • 收货地址
    • 收货人
    • 联系电话
    • 订单运费
    • 订单备注
    • 订单状态
  • OrderGoods 表, 存储订单所对应的商品信息.
    • 订单商品
    • 商品数量
    • 所属订单

针对我们分析的表结构, 我们创建对应的模型, 首先是创建商品展示相关的两个模型类, 在 goods 应用的 models.py 模块中编辑如下代码:

代码语言:javascript复制
class GoodsCategory(models.Model):
    """商品分类模型"""
​
    # 分类名称
    cag_name = models.CharField(max_length=30)
    # 分类样式
    cag_css = models.CharField(max_length=20)
    # 分类图片
    cag_img = models.ImageField(upload_to='cag')
​
​
class GoodsInfo(models.Model):
    """商品信息模型"""
​
    # 商品名字
    goods_name = models.CharField(max_length=100)
    # 商品单位
    goods_unit = models.CharField(max_length=50)
    # 商品价格
    goods_price = models.IntegerField(default=0)
    # 商品图片
    goods_img = models.ImageField(upload_to='goods')
    # 商品描述
    goods_desc = models.CharField(max_length=2000)
    # 所属分类
    goods_cag = models.ForeignKey('GoodsCategory')

注意点:

  • 模型类需要定义在 models.py 模块中.
  • 模型类必须继承自 models.Model 类.
  • 每一个类属性和数据库表中的一个字段一一对应.

类属性后面的字段类型是由 Django 定义, 方便将字段类型映射到不同的数据库中. 例如如下代码:

代码语言:javascript复制
goods_name = models.CharField(max_length=100)

字段名叫做 goods_name, 字段的类型为 CharField, 对应到 MySQL 数据库的字段类型就为 varchar 类型, 并且长度为100. 除了 CharField, 我们还发现有其他不同的字段类型, 常用字段类型以及含义如下表所示:

使用时需要引入 django.db.models 包,字段类型如下:

字段类型

描述

AutoField

自动增长的IntegerField,通常不用指定,不指定时Django会自动创建属性名为id的自动增长属性.

BooleanField

布尔字段,值为True或False.

NullBooleanField

支持Null、True、False三种值.

CharField(max_length=长度)

字符串, 参数max_length表示最大字符个数.CharField必须指定max_length大小

TextField

大文本字段

IntegerField

IntegerField 一个整数. 在Django所支持的所有数据库中,从 -2147483648 到 2147483647 范围内的值是合法的.

DecimalField(max_digits=None, decimal_places=None)

十进制浮点数.参数max_digits表示总位数.参数decimal_places表示小数位数.

DateField[auto_now=False, auto_now_add=False])

日期. 参数auto_now表示每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是使用当前日期,默认为false.参数auto_now_add表示当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为false.参数auto_now_add和auto_now是相互排斥的,组合将会发生错误.

TimeField

时间,参数同DateField

DateTimeField

日期时间,参数同DateField.

FileField

上传文件字段.

ImageField

继承于FileField,对上传的内容进行校验,确保是有效的图片.

BigIntegerField

一个64位整数, 类似于一个 IntegerField ,它的值的范围是 -9223372036854775808 到9223372036854775807之间.

SmallIntegerField

该字段值在 -32768 至 32767

表中并未解释 models.ForeignKey 字段的含义, 该字段主要用于建立外键, 表示表和表之间是一对多的关系, 例如, 商品分类和商品信息表之间就属于一对多的关系. 我们就可在商品信息模型中建立对商品分类的外键.

每个字段都会有一些字段选项:

选项类型

描述

null

如果为True,表示允许为空,默认值是False.

db_column

字段的名称,如果未指定,则使用属性的名称.

db_index

若值为True, 则在表中会为此字段创建索引,默认值是False.

default

默认值

primary_key

若为True,则该字段会成为模型的主键字段,默认值是False,一般作为AutoField的选项使用.

unique

如果为True, 这个字段在表中必须有唯一值,默认值是False.

  • null.如果为True,Django 将会把数据库中空值保存为NULL。默认值是 False.
  • blank. 如果为True,该字段允许为空值,默认为False。要注意,这与 null 不同。null纯粹是数据库范畴,指数据库中字段内容是否允许为空,而 blank 是表单数据输入验证范畴的。如果一个字段的blank=True,表单的验证将允许输入一个空值。如果字段的blank=False,该字段就是必填的。
  • primary_key.如果为True,那么这个字段就是模型的主键。如果你没有指定任何一个字段的primary_key=True,Django 就会自动添加一个IntegerField 字段做为主键,所以除非你想覆盖默认的主键行为,否则没必要设置任何一个字段的primary_key=True。主键字段是只读的。如果你在一个已存在的对象上面更改主键的值并且保存,一个新的对象将会在原有对象之外创建出来。

下面我们在 cart 应用的 models.py 模块中创建购物车相关的模型类, 代码如下:

代码语言:javascript复制
class OrderInfo(models.Model):
    """订单信息模型"""
​
    status = (
        (1, '待付款'),
        (2, '待发货'),
        (3, '待收货'),
        (4, '已完成'),
    )
​
    # 订单编号
    order_id = models.CharField(max_length=100)
    # 收货地址
    order_addr = models.CharField(max_length=100)
    # 收货人
    order_recv = models.CharField(max_length=50)
    # 联系电话
    order_tele = models.CharField(max_length=11)
    # 运费
    order_fee = models.IntegerField(default=10)
    # 订单备注
    order_extra = models.CharField(max_length=200)
    # 订单状态
    order_status = models.IntegerField(default=1, choices=status)
​
​
class OrderGoods(models.Model):
    """订单商品模型"""
​
    # 所属商品
    goods_info = models.ForeignKey('goods.GoodsInfo')
    # 商品数量
    goods_num = models.IntegerField()
    # 商品所属订单
    goods_order = models.ForeignKey('OrderInfo')

如下代码:

代码语言:javascript复制
order_status = models.IntegerField(default=1, choices=status)

该代码中的 choices=status 表示的值为 status 指定的 4 个值中的一个.

我们所需要的模型创建好了, 下面就需要 Django 按照我们所定义的模型类来创建对应的数据库表. 首先我们先查看下项目目录结构, 会发现在 goods 应用和 cart 应用的 migrations 目录为空, 当我们执行迁移命令时, 对比该目录的变化:

图6

下面在终端执行迁移命令:

代码语言:javascript复制
python manage.py makemigrations

命令执行效果如图7所示:

图7

下面我们再来看看 migrations 目录, 我们会发现多出名为 0001_initial.py 文件.

图8

0001_initial.py 文件我们可以理解为 SQL 的配置文件, 我们可将其转换为 SQL语句, 执行如下命令:

代码语言:javascript复制
python manage.py sqlmigrate goods 0001

表示将 goods 应用下的 0001 配置文件转换为 SQL语句, 效果如图9所示:

图9

下面我们执行迁移命令, 执行对应的 SQL 语句, 在数据库中创建对应的数据库表, 执行迁移的命令如下:

代码语言:javascript复制
python manage.py migrate

执行效果如图10所示:

图10

查看数据库, 我们已发现对应的数据库表已经创建, 但是表明并不是我们和我们模型类类名一直, 数据库中的表的格式为: 应用名字_模型类类名小写.

图11

对应模型的4张表名字分别为: cart_ordergoods、cart_orderinfo、goods_goodscategory、goods_goodsinfo.

0 人点赞