###目录:
Django模型(数据库)及Django Query常用方法
Django 模型是与数据库相关的,与数据库相关的代码一般写在 models.py
中,Django 支持 sqlite3, MySQL, PostgreSQL等数据库,只需要在settings.py
中配置即可,不用更改models.py
中的代码,丰富的API极大的方便了使用。
新建项目和应用
1 | 复制代码django-admin.py startproject learn_models # 新建一个项目 |
补充:新建app也可以用 python manage.py startapp people
, 需要指出的是,django-admin.py
是安装Django后多出的一个命令,并不是运行的当前目录下的django-admin.py
(当前目录下也没有),但创建项目会生成一个 manage.py
文件。
那project和app什么关系呢?
一个项目一般包含多个应用,一个应用也可以用在多个项目中。
添加应用
将我们新建的应用(people)添加到 settings.py 中的 INSTALLED_APPS中,也就是告诉Django有这么一个应用。
1 | 复制代码INSTALLED_APPS = ( |
修改models.py
我们打开 people/models.py 文件,修改其中的代码如下:
1 | 复制代码from django.db import models |
我们新建了一个Person类,继承自models.Model, 一个人有姓名和年龄。
这里用到了两种Field,更多Field类型可以参考教程最后的链接。
创建数据表
我们来同步一下数据库(我们使用默认的数据库 SQLite3,无需配置)
1 | 复制代码先 cd 进入 manage.py 所在的那个文件夹下,输入下面的命令 |
我们会看到,Django生成了一系列的表,也生成了我们新建的people_person这个表,那么如何使用这个表呢?
使用 Django 提供的 QuerySet API
Django提供了丰富的API, 下面演示如何使用它。
1 | 复制代码$ python manage.py shell |
我们新建了一个用户WeizhongTu 那么如何从数据库是查询到它呢?
1 | 复制代码>>> Person.objects.get(name="Tom") |
我们用了一个 .objects.get() 方法查询出来符合条件的对象,但是大家注意到了没有,查询结果中显示<Person: Person object>,这里并没有显示出与Tom的相关信息,如果用户多了就无法知道查询出来的到底是谁,查询结果是否正确,我们重新修改一下 people/models.py
name 和 age 等字段中不能有 __(双下划线,因为在Django QuerySet API中有特殊含义(用于关系,包含,不区分大小写,以什么开头或结尾,日期的大于小于,正则等)
也不能有Python中的关键字,name 是合法的,student_name 也合法,但是student__name不合法,try, class, continue 也不合法,因为它是Python的关键字( import keyword; print(keyword.kwlist) 可以打出所有的关键字)
1 | 复制代码from django.db import models |
按 CTRL + C 退出当前的 Python shell, 重复上面的操作,再来看看效果
新建一个对象的方法有以下几种:
1 | 复制代码1. Person.objects.create(name=name,age=age) |
这种方法是防止重复很好的方法,但是速度要相对慢些,返回一个元组,第一个为Person对象,第二个为True或False, 新建时返回的是True, 已经存在时返回False.
获取对象有以下方法:
1 | 复制代码Person.objects.all() |
get是用来获取一个对象的,如果需要获取满足条件的一些人,就要用到filter
1 | 复制代码Person.objects.filter(name="abc") |
filter是找出满足条件的,当然也有排除符合某条件的
1 | 复制代码Person.objects.exclude(name__contains="WZ") |
从数据库中查询出来的结果一般是一个集合,这个集合叫做 QuerySet。
1 | 复制代码from django.db import models |
QuerySet 创建对象的方法
1 | 复制代码>>> from blog.models import Blog |
备注:前三种方法返回的都是对应的 object,最后一种方法返回的是一个元组,(object, True/False),创建时返回 True, 已经存在时返回 False
当有一对多,多对一,或者多对多的关系的时候,先把相关的对象查询出来
1 | 复制代码>>> from blog.models import Entry |
删除符合条件的结果
和上面类似,得到满足条件的结果,然后 delete 就可以(危险操作,正式场合操作务必谨慎),比如:
1 | 复制代码Person.objects.filter(name__contains="abc").delete() # 删除 名称中包含 "abc"的人 |
更新某个内容
批量更新,适用于 .all() .filter() .exclude() 等后面 (危险操作,正式场合操作务必谨慎)
1 | 复制代码Person.objects.filter(name__contains="abc").update(name='xxx') # 名称中包含 "abc"的人 都改成 xxx |
单个 object 更新,适合于 .get(), get_or_create(), update_or_create() 等得到的 obj,和新建很类似。
1 | 复制代码aut = Author.objects.get(name="Sara") |
QuerySet 是可迭代的,比如:
1 | 复制代码es = Entry.objects.all() |
Entry.objects.all() 或者 es 就是 QuerySet 是查询所有的 Entry 条目。
注意事项:
(1). 如果只是检查 Entry 中是否有对象,应该用 Entry.objects.all().exists()
(2). QuerySet 支持切片 Entry.objects.all()[:10] 取出10条,可以节省内存
(3). 用 len(es) 可以得到Entry的数量,但是推荐用 Entry.objects.count()来查询数量,后者用的是SQL:SELECT COUNT(*)
(4). list(es) 可以强行将 QuerySet 变成 列表
QuerySet 查询结果排序
作者按照名称排序
1 | 复制代码Author.objects.all().order_by('name') |
QuerySet 支持链式查询
1 | 复制代码Author.objects.filter(name__contains="Tom").filter(email="tom@163.com") |
QuerySet 不支持负索引
1 | 复制代码Person.objects.all()[:10] 切片操作,前10条 |
扩展:QuerySet 重复的问题,使用 .distinct() 去重复
一般的情况下,QuerySet 中不会出来重复的,重复是很罕见的,但是当跨越多张表进行检索后,结果并到一起,可以会出来重复的值
1 | 复制代码qs1 = Pathway.objects.filter(label__name='x') |
##实例代码操作
需求一:编写登录和注册
编写注册功能,用户名不能已经存在,如果存在需要提示重新输入
注册后可以登录,成功后可以跳转到成功登录界面
代码操作:
- register.html
1 | 复制代码<!DOCTYPE html> |
- login.html
1 | 复制代码<!DOCTYPE html> |
- loginsuc.html
1 | 复制代码<!DOCTYPE html> |
- weekForm.py
1 | 复制代码# -*- coding:utf-8 -*- |
- models.py
1 | 复制代码# -*- coding: utf-8 -*- |
- views.py
1 | 复制代码# -*- coding: utf-8 -*- |
- urls.py
1 | 复制代码from django.conf.urls import url |
效果展示:
需求二:编写宠物管理系统
- petForm.py
1 | 复制代码 |
- html
- petlist.html
1 | 复制代码<!DOCTYPE html> |
- html
- addpet.html
1 | 复制代码<!DOCTYPE html> |
- html
- editpet.html
1 | 复制代码<!DOCTYPE html> |
- models.py
1 | 复制代码# -*- coding: utf-8 -*- |
- views.py
1 | 复制代码# -*- coding: utf-8 -*- |
- urls.py
1 | 复制代码from django.conf.urls import url |
效果展示:
####功能完善中,未完待续…
本文转载自: 掘金