models.py
ORM(Object Relational Mapping)是对象关系映射。
from django.db import models
django模型是和数据库关联的,代码放在models.py,数据库信息在settings.py中统一配置即可。
每个模型对应数据库唯一的一张表,是django.db.models.Model的子类。
每个模型实例代表数据库中的一条特定记录.
模型的每个属性都表示为数据库中的一个字段。
-
在项目的settings.py中激活应用,并设置数据库相关参数。
-
让django包含你的应用:
告诉django你对模型做了更改,并且将这些更改存储为迁移文件polls/migrations/0001_initial.py:
$python manage.py makemigrations polls
可以查看迁移文件执行了哪些sql语句,并不真的在数据库执行:
$python manage.py sqlmigrate polls 0001
可以检查项目中的模型是否存在问题:
$python manage.py check
在数据库中创建模型,查找还没有被应用的迁移文件然后和数据库同步:
$python manage.py migrate
模型的字段类型和字段选项
模型的每个属性都表示为数据库的一个字段,是Field子类的某个实例。
模型的字段还有一些选项。
字段命名规则:
- 不能是python的保留关键字。
- 字段名中连续的下划线不能超过一个。
访问其它应用的模型,导入即可:
from <other-aplication>.models import <module-name>
模型字段类型和选项参考:
http://python.usyiyi.cn/documents/django_182/ref/models/fields.html#common-model-field-options
模型字段类型
字段的类型都是Field类的子类:
每个字段都接受一个可选的位置参数(一般是第一个),叫字段的自述名,如果不指定就默认是字段名字(下划线换成空格)。
自增字段:
AutoField
# 默认django会每个模型添加一个自增主键字段,如果你显示设置一个自增主键字段就不会默认再添加,每个模型只能有一个主键字段。
# id = models.AutoField(primary_key=True)
普通字段:
BigIntegerField
BinaryField
BooleanField
CharField
CommaSeparatedIntegerField
DateField
DateTimeField
DecimalField
DurationField
EmailField
FileField
FilePathField
FloatField
GenericIPAddressField
IPAddressField
ImageField
IntegerField
NullBooleanField
PositiveIntegerField
PositiveSmallIntegerField
SlugField
SmallIntegerField
TextField
TimeField
URLField
UUIDField
关系字段:
django定义了一系列字段类型描述数据库之间的关联:
这三个字段要求第一个参数是模型类,用verbose_name选项才能指定自述名。
ForeignKey 定义多对一关系
OneToOneField 定义一对一关系
ManyToManyField 定义多对多关系
执行查询
一旦建立数据模型,django会自动生成一套抽象的API,用于创建,检索,更新和删除对象.
创建对象
q = Question(question_text='content', pub_date='date')
q.save()
q = Question(question_text='content')
q.pub_date='date'
q.save()
Question.objects.create(question_text="content", pub_date='date')
# 防止重复,不存在就创建,返回(object, True),存在返回(object, False)
Question.objects.get_or_create(question_text='content', pub_date='date')
获取对象
通过模型中的管理器构造一个查询集来从数据库获取对象.
查询集求值:
- 迭代
- 切片
- 序列化
- repr()
- len()
- list()
- bool()
查询集参考QuerySet类的方法:
http://python.usyiyi.cn/translate/django_182/ref/models/querysets.html#queryset-api
# 获取表中所有对象
Question.objects.all()
# 切片获取部分
Question.objects.all()[:10]
# 获取单个
Question.objects.get(question_text='content')
# 过滤
Question.objects.filter(**kwargs)
Question.objects.exclude(**kwargs)
查询集的链式过滤:
Question.objects.all().exists()
Question.objects.all().order_by('name')
Question.objects.filter(**kwargs).filter(**kwargs)
select_related() QuerySet 方法会提前递归地预加载所有一对多关系的缓存。适合OneToOneField和ForeignKey。
Question.objects.select_related('related_model').all()
prefetch_related() QuerySet 方法会提前预加载所有多对多关系的缓存。适合ManyToManyField。
Question.objects.prefetch_related('related_model').all()
Q对象复杂查询
from django.db.models import Q
# 逻辑或
Question.objects.filter(Q(question_text='content') | Q(pub_date='date'))
# 逻辑与
Question.objects.filter(Q(question_text='content') & Q(pub_date='date'))
# 逻辑非
Question.objects.exclude(Q(question_text='content'))