django数据库查询
Python代码收藏代码
classBlog(models.Model):
name=models.CharField(max_length=100)
tagline=models.TextField()
def__unicode__(self):
returnself.name
classAuthor(models.Model):
name=models.CharField(max_length=50)
email=models.EmailField()
def__unicode__(self):
returnself.name
classEntry(models.Model):
blog=models.ForeignKey(Blog)
headline=models.CharField(max_length=255)
body_text=models.TextField()
pub_date=models.DateTimeField()
authors=models.ManyToManyField(Author)
def__unicode__(self):
returnself.headline
这是model,有blog,author,以及entry;其中entry分别与blog与author表关联,entry与blog表是通过外键(models.ForeignKey())相连,属于一对多的关系,即一个entry对应多个blog,entry与author是多对多的关系,通过modles.ManyToManyField()实现。
一、插入数据库,用save()方法实现,如下:
>>>frommysite.blog.modelsimportBlog
>>>b=Blog(name='BeatlesBlog',tagline='AllthelatestBeatlesnews.')
>>>b.save()
二、更新数据库,也用save()方法实现,如下:
>>b5.name='Newname'
>>b5.save()
保存外键和多对多关系的字段,如下例子:
更新外键字段和普通的字段一样,只要指定一个对象的正确类型。
>>>cheese_blog=Blog.objects.get(name="CheddarTalk")
>>>entry.blog=cheese_blog
>>>entry.save()
更新多对多字段时又一点不太一样,使用add()方法添加相关联的字段的值。
>>joe=Author.objects.create(name="Joe")
>>entry.authors.add(joe)
三、检索对象
>>>Blog.objects
<django.db.models.manager.Managerobjectat...>
>>>b=Blog(name='Foo',tagline='Bar')
>>>b.objects
Traceback:
...
AttributeError:"Managerisn'taccessibleviaBloginstances."
1、检索所有的对象
>>>all_entries=Entry.objects.all()
使用all()方法返回数据库中的所有对象。
2、检索特定的对象
使用以下两个方法:
fileter(**kwargs)
返回一个与参数匹配的QuerySet,相当于等于(=).
exclude(**kwargs)
返回一个与参数不匹配的QuerySet,相当于不等于(!=)。
Entry.objects.filter(pub_date__year=2006)
不使用Entry.objects.all().filter(pub_date__year=2006),虽然也能运行,all()最好再获取所有的对象时使用。
上面的例子等同于的sql语句:
slect*fromentrywherepub_date_year='2006'
链接过滤器:
>>>Entry.objects.filter(
...headline__startswith='What'
...).exclude(
...pub_date__gte=datetime.now()
...).filter(
...pub_date__gte=datetime(2005,1,1)
...)
最后返回的QuerySet是headlinelike'What%'andput_date<now()andpub_date>2005-01-01
另外一种方法:
>>q1=Entry.objects.filter(headline__startswith="What")
>>q2=q1.exclude(pub_date__gte=datetime.now())
>>q3=q1.filter(pub_date__gte=datetime.now())
这种方法的好处是可以对q1进行重用。
QuerySet是延迟加载
只在使用的时候才会去访问数据库,如下:
>>>q=Entry.objects.filter(headline__startswith="What")
>>>q=q.filter(pub_date__lte=datetime.now())
>>>q=q.exclude(body_text__icontains="food")
>>>printq
在printq时才会访问数据库。
其他的QuerySet方法
>>>Entry.objects.all()[:5]
这是查找前5个entry表里的数据
>>>Entry.objects.all()[5:10]
这是查找从第5个到第10个之间的数据。
>>>Entry.objects.all()[:10:2]
这是查询从第0个开始到第10个,步长为2的数据。
>>>Entry.objects.order_by('headline')[0]
这是取按headline字段排序后的第一个对象。
>>>Entry.objects.order_by('headline')[0:1].get()
这和上面的等同的。
>>>Entry.objects.filter(pub_date__lte='2006-01-01')
等同于SELECT*FROMblog_entryWHEREpub_date<='2006-01-01';
>>>Entry.objects.get(headline__exact="Manbitesdog")
等同于SELECT...WHEREheadline='Manbitesdog';
>>>Blog.objects.get(id__exact=14)#Explicitform
>>>Blog.objects.get(id=14)#__exactisimplied
这两种方式是等同的,都是查找id=14的对象。
>>>Blog.objects.get(name__iexact="beatlesblog")
查找name="beatlesblog"的对象,不去饭大小写。
Entry.objects.get(headline__contains='Lennon')
等同于SELECT...WHEREheadlineLIKE'%Lennon%';
startswith等同于sql语句中的namelike'Lennon%',
endswith等同于sql语句中的namelike'%Lennon'.
>>>Entry.objects.filter(blog__name__exact='BeatlesBlog')
查找entry表中外键关系blog_name='BeatlesBlog'的Entry对象。
>>>Blog.objects.filter(entry__headline__contains='Lennon')
查找blog表中外键关系entry表中的headline字段中包含Lennon的blog数据。
Blog.objects.filter(entry__author__name='Lennon')
查找blog表中外键关系entry表中的author字段中包含Lennon的blog数据。
Blog.objects.filter(entry__author__name__isnull=True)
Blog.objects.filter(entry__author__isnull=False,entry__author__name__isnull=True)
查询的是author_name为null的值
Blog.objects.filter(entry__headline__contains='Lennon',entry__pub_date__year=2008)
Blog.objects.filter(entry__headline__contains='Lennon').filter(entry__pub_date__year=2008)
这两种查询在某些情况下是相同的,某些情况下是不同的。第一种是限制所有的blog数据的,而第二种情况则是第一个filter是
限制blog的,而第二个filter则是限制entry的
>>>Blog.objects.get(id__exact=14)#Explicitform
>>>Blog.objects.get(id=14)#__exactisimplied
>>>Blog.objects.get(pk=14)#pkimpliesid__exact
等同于select*fromwhereid=14
#Getblogsentrieswithid1,4and7
>>>Blog.objects.filter(pk__in=[1,4,7])
等同于select*fromwhereidin{1,4,7}
#Getallblogentrieswithid>14
>>>Blog.objects.filter(pk__gt=14)
等同于select*fromid>14
>>>Entry.objects.filter(blog__id__exact=3)#Explicitform
>>>Entry.objects.filter(blog__id=3)#__exactisimplied
>>>Entry.objects.filter(blog__pk=3)#__pkimplies__id__exact
这三种情况是相同的
>>>Entry.objects.filter(headline__contains='%')
等同于SELECT...WHEREheadlineLIKE'%\%%';
CachingandQuerySets
>>>print[e.headlineforeinEntry.objects.all()]
>>>print[e.pub_dateforeinEntry.objects.all()]
应改写为:
>>queryset=Poll.objects.all()
>>>print[p.headlineforpinqueryset]#Evaluatethequeryset.
>>>print[p.pub_dateforpinqueryset]#Re-usethecachefromtheevaluation.、
这样利用缓存,减少访问数据库的次数。
四、用Q对象实现复杂的查询
Q(question__startswith='Who')|Q(question__startswith='What')
等同于WHEREquestionLIKE'Who%'ORquestionLIKE'What%'
Poll.objects.get(
Q(question__startswith='Who'),
Q(pub_date=date(2005,5,2))|Q(pub_date=date(2005,5,6))
)
等同于SELECT*frompollsWHEREquestionLIKE'Who%'AND(pub_date='2005-05-02'ORpub_date='2005-05-06')
Poll.objects.get(
Q(pub_date=date(2005,5,2))|Q(pub_date=date(2005,5,6)),
question__startswith='Who')
等同于Poll.objects.get(question__startswith='Who',Q(pub_date=date(2005,5,2))|Q(pub_date=date(2005,5,6)))
五、比较对象
>>>some_entry==other_entry
>>>some_entry.id==other_entry.id
六、删除
Entry.objects.filter(pub_date__year=2005).delete()
b=Blog.objects.get(pk=1)
#ThiswilldeletetheBlogandallofitsEntryobjects.
b.delete()
Entry.objects.all().delete()
删除所有
七、一次更新多个值
#Updatealltheheadlineswithpub_datein2007.
Entry.objects.filter(pub_date__year=2007).update(headline='Everythingisthesame')
>>>b=Blog.objects.get(pk=1)
#ChangeeveryEntrysothatitbelongstothisBlog.
>>>Entry.objects.all().update(blog=b)
如果用save()方法,必须一个一个进行保存,需要对其就行遍历,如下:
foriteminmy_queryset:
item.save()
关联对象
one-to-many
>>>e=Entry.objects.get(id=2)
>>>e.blog#ReturnstherelatedBlogobject.
>>>e=Entry.objects.get(id=2)
>>>e.blog=some_blog
>>>e.save()
>>>e=Entry.objects.get(id=2)
>>>e.blog=None
>>>e.save()#"UPDATEblog_entrySETblog_id=NULL...;"
>>>e=Entry.objects.get(id=2)
>>>printe.blog#HitsthedatabasetoretrievetheassociatedBlog.
>>>printe.blog#Doesn'thitthedatabase;usescachedversion.
>>>e=Entry.objects.select_related().get(id=2)
>>>printe.blog#Doesn'thitthedatabase;usescachedversion.
>>>printe.blog#Doesn'thitthedatabase;usescachedversion
>>>b=Blog.objects.get(id=1)
>>>b.entry_set.all()#ReturnsallEntryobjectsrelatedtoBlog.
#b.entry_setisaManagerthatreturnsQuerySets.
>>>b.entry_set.filter(headline__contains='Lennon')
>>>b.entry_set.count()
>>>b=Blog.objects.get(id=1)
>>>b.entries.all()#ReturnsallEntryobjectsrelatedtoBlog.
#b.entriesisaManagerthatreturnsQuerySets.
>>>b.entries.filter(headline__contains='Lennon')
>>>b.entries.count()
YoucannotaccessareverseForeignKeyManagerfromtheclass;itmustbeaccessedfromaninstance:
>>>Blog.entry_set
add(obj1,obj2,...)
Addsthespecifiedmodelobjectstotherelatedobjectset.
create(**kwargs)
Createsanewobject,savesitandputsitintherelatedobjectset.Returnsthenewlycreatedobject.
remove(obj1,obj2,...)
Removesthespecifiedmodelobjectsfromtherelatedobjectset.
clear()
Removesallobjectsfromtherelatedobjectset.
many-to-many类型:
e=Entry.objects.get(id=3)
e.authors.all()#ReturnsallAuthorobjectsforthisEntry.
e.authors.count()
e.authors.filter(name__contains='John')
a=Author.objects.get(id=5)
a.entry_set.all()#ReturnsallEntryobjectsforthisAuthor.
one-to-one类型:
classEntryDetail(models.Model):
entry=models.OneToOneField(Entry)
details=models.TextField()
ed=EntryDetail.objects.get(id=2)
ed.entry#ReturnstherelatedEntryobject
使用sql语句进行查询:
defmy_custom_sql(self):
fromdjango.dbimportconnection
cursor=connection.cursor()
cursor.execute("SELECTfooFROMbarWHEREbaz=%s",[self.baz])
row=cursor.fetchone()
returnrow