【回顾·创建模型类流程】

  1. 创建应用
  2. 在应用下的models.py中编写数据类
  3. 迁移同步 makemigrations和migrate

****任何关于表结构的修改,务必在对应模型类上修改

****修改过字段选项(添加or更改)均要执行makemigrations和migrate

【模型类的字段类型】

  • BooleanField()
    1. 数据库类型:tinyint(1)
    2. 在编程语言中:使用True或False来表示值
    3. 在数据库中:使用1或0来表示具体的值
  • CharField()
    1. 数据库类型:varchar
    2. 注意:必须要指定max_length参数值!!!
  • DateField()
    1. 数据库类型:date
    2. 作用:表示日期
    3. 参数:(以下三个参数只能设置一个为True)
      1. auto_now:将 每次保存对象时的时间 自动设置为该字段的时间(取值True/False)
      2. auto_now_add:将 对象第一次被创建时的时间 自动设置为该字段的时间(取值True/False)
      3. default:自定义时间(取值:字符串格式时间,如:'2019-6-1')
  • DateTimeField()
    1. 数据库类型:datetime(6)
    2. 作用:表示日期和时间
    3. 参数:同DateField()
  • FloatField()
    1. 数据库类型:double
    2. 编程语言中和数据库中都使用小数表示值
  • DecimalField()
    1. 数据库类型:decimal(x, y)
    2. 在编程语言中:使用小数表示该列的值
    3. 在数据库中:使用小数
    4. 参数:
      1. max_digits:位数总数,包括小数点后的位数。该值必须大于等于decimal_places的值
      2. decimal_places:小数点后的位数
  • EmailField()
    1. 数据库类型:varchar(Django中设置了正则)
    2. 编程语言与数据库中都使用字符串
  • IntegerField()
    1. 数据库类型:int
    2. 编程语言与数据库中都使用整数
  • ImageField()
    1. 数据库类型:varchar(100)
    2. 作用:在数据库中为了保护图片的路径
    3. 编程语言和数据库中使用字符串
  • TextField()
    1. 数据库类型:longtext
    2. 作用:表示不定长的字符数据

【模型类的字段选项】

字段选项:指定创建的列的额外的信息

*允许出现多个字段选项,多个选项之间使用英文逗号隔开

  • primary_key:设置为True时,表示该列为主键,如果指定一个字段为主键,则此数据库表不会自动创建id字段。
  • blank:设置为True时,字段可以为空;设置为False时,字段必须填写。
  • null:设置为True时,表示该列的值允许为空。此字段选项默认为False,为False时,建议加入default选项来设置默认值。
  • default:设置所在列的默认值,如果字段选项null=False,则建议添加此项。
  • db_index:设置为True时,表示为该列增加索引。
  • unique:设置为True时,表示该字段在数据库中的值必须是唯一的(不能重复出现)。
  • db_column:可以指定列的名称,如果不指定,则采用属性名作为列名。
  • verbose_name:设置此字段在admin界面上的显示名称

# 样例:创建一个属性,表示用户名称,长度30个字符,必须唯一,不能为空,添加索引

name = models.CharField(max_length=30, unique=True, null=False, db_index=True)

【Meta类】

使用内部Meta类来给模型赋予属性,Meta类下有很多内建的类属性,可对模型类做一些控制(控制表相关属性)

>样例1:将表名bookstore_book修改为book

# file: bookstore/models.py
from django.db import models

class Book(models.Model):
    title = models.CharField("书名", max_length=50, default='')
    price = models.DecimalFiedl("定价", max_digits=7, decimal_places=2, default=0.0)

    class Meta:
        db_table = 'book'  # 修改了当前模型类对应的表名

<<常见问题汇总>>

1、当执行python3 manage.py makemigrations时,出现如下迁移错误:

错误原因:

  • 当对模型类新添加一个字段时可能出现该错误
  • 原理是:添加新字段后,数据库不知道原来已有数据对于新建字段该如何赋值,所以新增字段时,务必要添加default默认值

处理方法:

  • 方案1:进入到shell中,手动输入一个默认值
  • 方案2(推荐):退出当前生成迁移文件的过程,自己去修改models.py,新增加一个'default=XXX'的缺省值

2、数据库的迁移文件混乱问题

错误原因:数据库中django_migrations表记录了migrate的全过程,项目各应用中的migrate文件应与之对应,否则migrate会报错

解决方案:

  • 方案1:删除所有migrations中所有的000?_XXX.py(__init__.py除外)
  • 方案2:删除数据库(命令:drop database 数据库名)

【ORM基本操作】

基本操作包括增删改查操作,即CRUD。

ORM CRUD核心是:模型类.管理器对象

【管理器对象】

每个继承自models.Model的模型类,都会有一个objects对象被同样继承下来,这个对象就叫管理器对象。

数据库的增删改查操作可以通过模型的管理器实现。

【ORM基本操作-创建数据】

Django ORM 使用一种直观的方式把数据库表中的数据表示成Python对象,

创建数据中每一条记录就是创建一个数据对象。

  • 方案1:

MyModel.objects.create(属性1=值1, 属性2=值2, ...)

若运行成功,则返回创建好的实体对象;若失败,则立即抛出异常

  • 方案2:创建MyModel实例对象,并调用save()进行保存

obj = MyModel(属性1=值1, 属性2=值2, ...)

obj.属性=值  # 此行按照需求可有可无,可临时补充属性值

obj.save()

【Django Shell】

在Django提供了一个交互式的操作项目叫Django Shell,它能够在交互模式下用项目工程的代码执行相应的操作。

利用Django Shell可以代替编写view的代码来进行直接操作。

**注意:项目代码发生变化时,要重新进入Django Shell,保证代码最新

  • 启动方式:

python3 manage.py shell

  • 在Django Shell中创建数据:方案1(**注意:一定要导入模型类!!)

  • 在Django Shell中创建数据:方案2

【ORM基本操作-查询操作】

数据库的查询需要使用管理器对象进行,

通过MyModel.objects管理器方法调用查询方法。

方法说明
all()查询全部记录,返回QuerySet查询对象
get()查询符合条件的单一记录
filter()查询符合条件的多条记录
exclude()查询符合条件之外的全部记录
......

【查询方法】

  • all()
    • 用法:MyModel.objects.all()
    • 作用:查询MyModel实体中所有的数据(等同于SELECT * FROM mytabel)
    • 返回值:QuerySet容器对象,内部存放MyModel实例(类似类数组对象)

******可以在模型类中定义__str__方法,自定义QuerySet中的输出格式

如:在Book模型类(models.py中Book类)下定义如下:

    def __str__(self):
        return '%s_%s_%s_%s'%(self.title, self.price, self.pub, self.market_price)

则在Django Shell中可得到如下显示输出:

  • values('列1', '列2', ...)
    • 用法:MyModel.objects.values(...)
    • 作用:查询部分列的数据并返回(等同于SELECT 列1,列2 FROM mytable)
    • 返回值:QuerySet,返回查询结果容器,容器内存字典,每个字典代表一条数据,格式为{'列1':值1, '列2':值2}

  • values_list('列1', '列2', ...)
    • 用法:MyModel.objects.values_list(...)
    • 作用:返回元组形式的查询结果(等同于SELECT 列1,列2 FROM mytable)
    • 返回值:QuerySet容器对象,内部存放元组,会将查询出来的数据封装到元组中,再封装到查询集合QuerySet中

  • order_by()
    • 用法:MyModel.objects.order_by('-列','列')
    • 作用:与all()方法不同,它会用SQL语句的ORDER BY子句对查询结果进行根据某个字段选择性的进行排序
    • 说明:默认是按照升序排序,降序排序则需要在 列前增加 '-'号表示

>方法也可以组合起来使用,如:

value()和order_by()组合:

>使用.query可以查看SQL语句,如:

【条件查询】

  • filter(条件)
    • 语法:MyModel.objects.filter(属性1=值1, 属性2=值2)
    • 作用:返回包含此条件的全部的数据集
    • 返回值:QuerySet容器对象,内部存放MyModel实例
    • 说明:当有多个属性的条件时为“与”关系
  • exclude(条件)
    • 语法:MyModel.objects.exclude(条件)
    • 作用:返回不包含此条件的全部的数据集
  • get(条件)
    • 语法:MyModel.objects.get(条件)
    • 作用:返回满足条件的唯一一条数据
    • 说明:该方法只能返回一条数据。查询结果多于一条数据则抛出Model.MultipleObjectsReturned异常;查询结果如果没有数据则抛出Model.DoesNotExist异常

【查询谓词】

定义:做更灵活的条件查询时需要使用查询谓词

*每一个查询谓词是一个独立的查询功能

  • __exact:等值匹配
  • __contains:包含指定值
  • __startswith:以指定值开始
  • __endswith:以指定值结束
  • __gt:大于指定值
  • __gte:大于等于指定值
  • __lt:小于指定值
  • __lte:小于等于指定值
  • __in:查找数据是否在指定范围内
  • __range:查找数据是否在指定的区间范围内

# 等同于 SELECT * FROM MyModel WHERE id=1

MyModel.objects.filter(id__exact=1)

# 等同于 SELECT * FROM MyModel WHERE name LIKE '%w%'

MyModel.objects.filter(name__contains='w')

# 等同于 SELECT * FROM MyModel WHERE age>50

MyModel.objects.filter(age__gt=50)

# 等同于 SELECT * FROM MyModel WHERE country in ('中国', '日本', '韩国')

MyModel.objects.filter(country__in=['中国', '日本', '韩国'])

Logo

欢迎加入西安开发者社区!我们致力于为西安地区的开发者提供学习、合作和成长的机会。参与我们的活动,与专家分享最新技术趋势,解决挑战,探索创新。加入我们,共同打造技术社区!

更多推荐