模型
定义
在 models.py 中定义模型,模型都是 django.db.models.Model 的子类:
from django.db import models
class Reporter(models.Model):
# 定义字段类型和参数
full_name = models.CharField(max_length=70)
# 定义字符表示
def __str__(self):
return self.full_name
class Article(models.Model):
pub_date = models.DateField()
headline = models.CharField(max_length=200)
content = models.TextField()
# 外键,Article 和 Reporter 是多对一关系,且规定删除 Reporter 时 删除对应的 Article
reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
def __str__(self):
return self.headline
数据字段
常见的字段类型有:
BinaryFieldBooleanFieldCharFieldEmailField、FilePathField、URLField
TextFieldDateField、DateTimeField、DurationField、TimeFieldDecimalField、FloatFieldFileFieldImageField
JSONField
还有不少字段类型,设置特殊字段时值得看看,说不定有对应的,甚至还能自定义字段类型。
关系字段
关系字段有:
ForeignField:多对一ManyToManyField:多对多OneToOneField:一对一
此处只以 ForeignField 为例简单介绍。
from django.db import models
class Author(models.Model):
pass
class Book(models.Model):
# 外键到 Author,删除时 CASCADE
author = models.ForeignKey(to=Author, on_delete=models.CASCADE)
on_delete 可能的值:
CASCADE:to被删除时,该对象也被删除PROTECT:防止to被删除RESTRICT:有点复杂,见文档SET_NULL:to被删除时,设置外键为空SET_DEFAULT:to被删除时,设置外键为默认值SET()DO_NOTHING
注意 on_delete 不依赖数据库实现而是依赖 Django 实现。
字段选项
一些通用的字段选项,且都是可选的。
| 选项 | 默认值 | 说明 |
|---|---|---|
blank |
False |
是否可以为空,这个只是表单端 |
null |
False |
空值实际存储为 NULL,例如字符串默认空值为空字符串,就不建议设置 null 为 True |
choices |
提供选项,类似枚举,详见文档 | |
db_column |
数据库列名 | |
db_index |
为该字段创建索引 | |
db_tablespace |
字段索引使用的的表空间 | |
default |
字段默认值,可以是一个函数 | |
editable |
True |
若为否,则会跳过模型验证,也不会在管理界面或 ModelForm 中出现 |
error_messages |
自定义错误信息 | |
help_text |
帮助文本 | |
primary_key |
设置为模型主键,且 null=False, unique=True |
|
unique |
保证唯一性,且自动创建索引 | |
unique_for_date |
另一个字段(DateField 或 DateTimeField)的名称,从而保证该字段和另一个字段的日期部分不同,注意时间部分忽略哦 |
|
unique_for_month |
同上 | |
unique_for_year |
同上 | |
verbose_name |
人类可读名称,不设置的话 Django 会自动设置 | |
validators |
验证器 |
元数据 Meta
在模型中嵌套一个 Meta 类,用于定义模型的元数据,如排序、数据库表名等,见文档。
使用
# 代码高亮不太对,不要在意
# 导入模型
>>> from news.models import Article, Reporter
# 全部 Reporter
>>> Reporter.objects.all()
<QuerySet []>
# 创建 Reporter 并保存
>>> r = Reporter(full_name='John Smith')
>>> r.save()
>>> Reporter.objects.all()
<QuerySet [<Reporter: John Smith>]>
>>> r.id
1
>>> r.full_name
'John Smith'
# 根据字段查询
>>> Reporter.objects.get(id=1)
<Reporter: John Smith>
>>> Reporter.objects.get(full_name__startswith='John')
<Reporter: John Smith>
>>> Reporter.objects.get(full_name__contains='mith')
<Reporter: John Smith>
>>> Reporter.objects.get(id=2)
Traceback (most recent call last):
...
DoesNotExist: Reporter matching query does not exist.
# 创建 Article 并保存,注意 reporter 是之前的 r
>>> from datetime import date
>>> a = Article(pub_date=date.today(), headline='Django is cool',
... content='Yeah.', reporter=r)
>>> a.save()
>>> Article.objects.all()
<QuerySet [<Article: Django is cool>]>
# 从 a 得到 reporter r
>>> r = a.reporter
>>> r.full_name
'John Smith'
# 查询 r 的所有 Article 得到 article a
>>> r.article_set.all()
<QuerySet [<Article: Django is cool>]>
# 查询所有 reporter 的全名以 John 开始的 Article
>>> Article.objects.filter(reporter__full_name__startswith='John')
<QuerySet [<Article: Django is cool>]>
# 更改 r 的全名
>>> r.full_name = 'Billy Goat'
>>> r.save()
# 删除 r
>>> r.delete()
Migration 相关命令
python manage.py makemigrations
python manage.py sqlmigrate
python manage.py migrate <app_label> <migration_name> [--backwards]