django模型
配置数据库
setting.py文件中的DATABASES设置
- ENGINE 告诉 Django 使用哪个数据库引擎
- NAME 告诉 Django 数据库的名称
Django应用
应用方面有个严守的约定:如果使用 Django 的数据库层(模型),必须创建 Django 应用。模型必须保存在应用中
- python manage.py startapp books<应用名称>
- 项目目录中生成目录结构:
books/ __init__.py # 告诉python该目录是一个python包 admin.py # 管理站点的声明文件,默认为空 apps.py # 应用信息定义文件,生成类AppConfig,用于定义应用名等Meta信息 migrations/ # 用于在之后定义引用迁移功能 __init__.py # 告诉python该目录是一个python包 models.py # 添加模型层数据类的文件 tests.py # 测试代码文件 views.py # 定义url响应函数
定义模型
一个模型对应于一个数据库表,每个模型使用一个 Python 类表示,而且是 django.db.models.Model 的子类,模型中的各个属性分别对应于数据库表中的一列。属性的名称对应于列的名称,字段的类型(如CharField )对应于数据库列的类型(如 varchar )
- 作者-书-出版社 模型定义例子:
在 startapp 命令创建的 models.py 文件中输入
from django.db import models
class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.CharField(max_length=50)
website = models.URLField()
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField()
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
publication_date = models.DateField()
- 安装模型:
- 激活那些模型,把books<应用>添加到设置文件中“安装的应用”列表中(settings.py 文件,找到 INSTALLED_APPS 设置)
- 验证模型:
python manage.py check
一切正常,你将看到: System check identified no issues (0 silenced) - 告诉 Django 对模型做了修改:
python manage.py makemigrations books
在migrate文件中生成0001_initial.py 的文件,也就是迁移 - 查看sql:
python manage.py sqlmigrate books 0001
sqlmigrate 命令的参数是迁移名称,输出的结果是对应的 SQL - 提交 SQL:
python manage.py migrate
基本的数据访问
以Publisher为例:
添加模型的字符串表现形式
-
publisher_list = Publisher.objects.all():获取全部Publisher对象
-
打印publisher_list时得到的是无用的输出,需要在Publisher类中添加一个名为__str__()的方法,告诉Python 如何以人类可读的形式显示对象,对 str() 方法的唯一要求是返回一个字符串对象。例如:
def __str__(self): return self.name
插入和更新数据
- 插入:
p = Publisher(name='Apress',
address='2855 Telegraph Ave.',
city='Berkeley',
state_province='CA',
country='U.S.A.',
SFJLkwebsite='http://www.apress.com/')
p.save() # 实例化模型类不会接触数据库。为了把记录保存到数据库中,要调用 save() 方法
p1 = Publisher.objects.create(name='Apress',
address='2855 Telegraph Avenue',
city='Berkeley',
state_province='CA',
country='U.S.A.',
website='http://www.apress.com/') # 创建的同时保存
- 更新:
p.name = 'Apress Publishing'
p.save() # 后续再调用 save() 将就地保存记录,而不新建记录(即,执行 SQL UPDATE 语句,而非 INSERT 语句),更新所有列
Publisher.objects.filter(id=52).update(name='Apress Publishing') # 更新单个列,语句更高效,而且不会导致条件竞争.update() 方法可以在任何 QuerySet 对象上调用
Publisher.objects.all().update(country='USA') # 批量编辑多个记录,update() 方法有返回值,是一个整数,表示修改的记录数量
查询对象
访问模型的objects 属性,叫管理器(manager),负责所有“表层”数据操作,包括(最重要的)数据查询。
- 过滤
Publisher.objects.filter(name='Apress') # filter() 的关键字参数转换成相应的 SQL WHERE 子句
Publisher.objects.filter(country="U.S.A.",state_province="CA") # 多个参数转换成 SQL AND 子句
Publisher.objects.filter(name__contains="press") # __contains 部分转换成 SQL LIKE 语句
- 单个对象
Publisher.objects.get(name="Apress") # get方法返回一个对象,得到多个对象会导致异常,不返回对象也导致异常
- 排序数据
Publisher.objects.order_by("name") # 任何字段排序
Publisher.objects.order_by("state_province", "address") # 多个字段排序,(以第一个字段排不出顺序时使用第二个字段)
Publisher.objects.order_by("-name") # 反向排序。方法是在字段名称前面加上“-”(减号)
class Meta:
ordering = ['name'] # 在模型中指定默认排序
- 链式查找
Publisher.objects.filter(country="U.S.A.").order_by("-name") # 排序和过滤
- 切片数据
Publisher.objects.order_by('name')[0] # 不支持使用负数,只显示第一个,LIMIT 1;
Publisher.objects.order_by('name')[0:2] # 范围切片句法检索数据子集,OFFSET 0 LIMIT 2;
删除对象
p = Publisher.objects.get(name="O'Reilly")
p.delete() # 想从数据库中删除一个对象,只需在对象上调用 delete() 方法
Publisher.objects.filter(country='USA').delete() # 可以在任何 QuerySet 对象上调用 delete() 方法,批量删除对象
Publisher.objects.all().delete() # 想删除表中的一切数据时,必须显式调用 all() 方法。