管理器(Manager)是Django的模型进行数据库查询操作的接口。Django 应用的每个模型都拥有至少一个管理器。默认情况下,Django 为每个模型类添加一个名为objects的管理器。管理器只能通过模型类访问,是对整个表进行操作的,不能通过模型实例访问。
以下面两个模型为例:
class Musician(models.Model): firstname= models.CharField(max_length=50) lastname= models.CharField(max_length=50) |
class Album(models.Model): musician = models.ForeignKey(Musician) name = models.CharField(max_length=100) |
一、创建实例(对应数据库中记录或元组)
创建一个对象实例的方法有以下几种:
(1) Musician.objects.create(firstname=”Jack”,lastname=”Lee”)
(2) p = Musician(firstname=”Jack”,lastname=”Lee”)
p.save()
(3) p = Musician(firstname=”Jack”)
p.lastname = “Lee”
p.save()
(4) Musician.objects.get_or_create(firstname=”Jack”,lastname=”Lee”)
注:第四种方法是防止重复很好的方法,但是速度要相对慢些,返回一个元组,第一个为Person对象,第二个为True或False,新建时返回的是True, 已经存在时返回False
(5) bulk_create
批量创建实例,只需访问一次数据库,可将一个列表对象写入数据库(立即生效,不需要save())
Musician.objects.bulk_create([
... Musician (firstname="Django1.0 Released"),
... Musician (firstname ="Django1.1 Announced"),
... Musician (firstname ="Breaking:Django is awesome")
... ])
对于带有ForeignKey(引用Musician)字段的Album,可使用p.Album_set.create(name=”song”)创建与p关联的Album对象实例。(反向访问)
注意:当你实例化一个模型时,Django是绝对不会对数据库进行读写的;若要保存实例化后的数据,你需要调用方法save()
二、查询记录
大多数情况下,需要从数据库中查找对象时,你会使用all()、 get()、filter() 和exclude()。
1. all():
返回了一个包含数据库表中所有记录查询集:
b = Musician.objects.all() 获取表中所有记录
b = Musician.objects.all()[:10] 获取前10个记录
2.get():
返回满足条件的一个记录:
b = Musician.objects.get(firstname=”Jack”)
3. filter():
返回满足条件的查询集:
b =Musician.objects.filter(firstname=”abc”) 获取firstname为abc的记录
b = Musician.objects.filter(firstname__exact=”abc”) 获取firstname严格为abc的记录
b = Musician.objects.filter(firstname__iexact=”abc”) 获取firstname不严格为abc的记录,如Abc
b = Musician.objects.filter(firstname__icontains=”abc”) 获取firstname中包含abc的,且abc不区分大小写
b = Musician.objects.filter(firstname__contains=”abc”) 获取firstname中包含abc的记录,
b = Musician.objects.filter(firstname__regex=”*abc”) 正则表达式查询
b = Musician.objects.filter(firstname__iregex=”*abc”) 正则表达式查询,不区分大小写
b= Musician.objects.filter(firstname=”abc”).order_by(“-lastname”) 对查询结果依据lastname进行降序排序
b =Musician.objects.filter(firstname=”abc”).distinct(“lastname”) 获取firstname为abc且lastname不重复的记录
4.exclude():
返回排除条件的查询集。
b = Musician.objects.exclude(firstname =”abc”) #获取firstname中不包含abc的记录
5.count():
返回在数据库中对应的 QuerySet.对象的个数。
Musician.objects.filter(firstname=”abc”).count()
6.exists() :
用于搜寻对象是否在QuerySet 中以及QuerySet 是否存在任何对象,特别是QuerySet 比较大的时候。它会试图用最简单和最快的方法完成查询。
if some_queryset.filter(pk=2).exists():
print("M contained in queryset")
7.(前向查询):
如果一个模型具有ForeignKey,那么该模型的实例将可以通过属性访问关联的(外部)对象如:
e = Album.objects.get(id=1)
e.firstname #获取与e相关联的Musician对象
8.(反向查询ForeignKey.related_name):
如果模型有一个ForeignKey,那么该ForeignKey所指的模型实例可以通过一个管理器返回那个定义ForeignKey模型的所有实例。默认情况下,这个管理器的名字为name_set(可在定义外键时设置related_name更改名字),其中name是源模型的小写名称。该管理器返回一个查询集。如:
e= Musician.objects.get(id=1)
e.album_set.all() #获取所有与e相关联的Album对象
9.(反向过滤ForeignKey.related_query_name)
这个名称用于目标模型的反向过滤,默认值为:(模型名称小写__属性)。用法如下:
Musician.objects.filter(album__name=”song”) #获取所有name=”song”的Musician对象
Album.onjects.filter(musician__firstname=”Jack”) #获取所有firstname = ”Jack”的Album对象
10.Q对象:
filter() 等方法中的关键字参数查询默认都是一起进行“AND” 的。 如果你需要执行更复杂的查询(例如OR 语句),你可以使用Q 对象。它相当于SQL中 WHERE 子句。如:
Musician.objects.get(Q(firstname__startswith=”Ja”)|Q(lastname=”Lee”))
注意:如果出现Q 对象,它必须位于所有关键字参数的前面。
11.在模型查询API不够用的情况下,你可以使用原始的SQL语句。
Django 提供两种方法使用原始SQL进行查询:一种是使用Manager.raw()方法,进行原始查询并返回模型实例;另一种是完全避开模型层,直接执行自定义的SQL语句。
Raw()方法:for p in Musician.objects.raw('SELECT* FROM myapp_musician'):
... print(p)
自定义:
from django.db import connection
def my_custom_sql(self):
cursor = connection.cursor()
cursor.execute("SELECT a FROM tableWHERE b = %s", [self.b])
row =cursor.fetchone()
return row
注意:(1)管理器可以进行链式查询,对获取的查询集结果,可再次进行查询,且每个查询集是独立的。如:b =Musician.objects.exclude(firstname =”*abc”) c = b.filter(lastname=”ha”)
(2) 查询集 是惰性执行的——创建查询集不会带来任何数据库的访问。你可以将过滤器保持一整天,直到查询集需要求值时,Django才会真正运行这个查询。如:print(c)、迭代、序列化、调用len() repr() list()等。
三、修改记录
1. update():
修改记录,可以批量修改。(立即生效,不需要save(),返回修改的记录个数)
Musician.objects.filter(firstname=”abc”).update(lastname=”LLL”) 修改firstname=abc的记录中lastname的值,并返回成功修改的记录条数。
禁止修改关联对象的字段,如:Musician.objects.filter(name=”aaa”).update(musician_lastname=”LLL”)是错误的。
四、删除
1. delete():
可以删除一条记录,也可以批量删除。(立即生效, 不需要save())
Musician.objects.filter(firstname=”abc”).delete 批量删除firstname为abc的记录
连接数据库:在setting.py中设置DATABASE项。包含Django 将使用的所有数据库的设置。它是一个嵌套的字典,其内容为数据库别名到包含数据库选项的字典的映射。DATABASES 设置必须配置一个default 数据库;可以同时指定任何数目的额外数据库。
如下为连接一个postgresql数据库:
DATABASES = {
'default': {
'ENGINE':'django.db.backends.postgresql_psycopg2',
'NAME': 'mydatabase',
'USER': 'mydatabaseuser',
'PASSWORD': 'mypassword',
'HOST': '127.0.0.1',
'PORT': '5432',
}
}