- model对应数据库表,model的实例则对应表中的一条记录.
from blog.models import Blog
b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.')
#调用save后才会在表中生成记录,b.id才会有值,因为id是数据库生成的
#此处save相当于调用了insert语句
b.save()
b.name="Tom"
#此处save相当于调用update语句
b.save()
#create方法包含创建对象并save到数据库 Blog.objects.create(name= 'news Blog', tagline= 'All news.') 添加ForeignKey和ManyToManyField的field值
from blog.models import Entry
entry = Entry.objects.get(pk=1)
cheese_blog = Blog.objects.get(name="Cheddar Talk")
#ForeighnKey成员,直接赋值
entry.blog = cheese_blog
entry.save()
#ManyToManyField成员需要调用add方法
joe = Author.objects.create(name="Joe")
entry.authors.add(joe)
#添加多个成员时
paul = Author.objects.create(name="Paul")
george = Author.objects.create(name="George")
ringo = Author.objects.create(name="Ringo")
entry.authors.add(paul,george,ringo)
- 每个model class都有一个Manager成员,默认名字为objects,注意是model class而不是model instance,Model.objects.all()返回所有QuerySet包含所有表中的对象.注意QuerySet是lazy的,创建时候并不会执行实际操作,只有evaluated时才真正执行操作。可以通过下面两个函数返回满足一定条件的QuerySet:
- filter(**kwargs):满足指定查询条件的QuerySet
- exclude(**kwargs):不满足查询条件的QuerySet
- 每个QuerySet都包含一个cache,以减少对数据库的访问,刚定义queryset时cache为空,evluated后cache就有值了,之后访问queryset都是访问cache中的值
#执行两次数据库查询
print([e.headline for e in Entry.objects.all()])
print([e.pub_date for e in Entry.objects.all()])
queryset = Entry.objects.all()
print([p.headline for p in queryset]) # Evaluate the query set.
print([p.pub_date for p in queryset]) # Re-use the cache from the evaluation.
queryset = Entry.objects.all()
#只返回queryset中的一部分
print queryset[5] # Queries the database
print queryset[5] # Queries the database again
queryset = Entry.objects.all()
[entry for entry in queryset] # Queries the database
print queryset[5] # Uses cache
print queryset[5] # Uses cache
#如下操作都会导致queryset evaluated,填充cache
[entry for entry in queryset]
bool(queryset)
entry in queryset
list(queryset)
- 可以返回QuerySet中的子集,相当于sql语句中的limit和offset
Entry.objects.all()[:5]
Entry.objects.all()[5:10]
Entry.objects.order_by('headline')[0]
- 返回单个对象使用get方法,如果对象不存在会抛出Model.DoesNotExist异常,如果有多个满足条件的对象则抛出Model.MultipleObjectsReturned异常。注意此处与QuerySet object[0]的区别,如果没有获取满足条件的QuerySet,用下标取对象会抛出IndexError的异常
- field查询:filter,get等函数都使用field进行查询,如果field不存在则会抛TypeError异常。例外的是以ForeignKey类型的field作查询参数时,可以在该field后面加”_id”,
#查找外键blog id=4的所有Entry
Entry.objects.filter(blog_id=4) 一些比较常用的查询关键字:
- exact:精确匹配,默认使用
#效果相同
Blog.objects.get(id__exact=14)
Blog.objects.get(id=14)
- iexact:匹配时忽略大小写
- contains:包含查询,大小写敏感
#相当于SELECT ... WHERE headline LIKE '%Lennon%';
Entry.objects.get(headline__contains='Lennon')
- icontains:包含查询,大小写不敏感
- startswith,endswith:匹配开头或结尾,大小写敏感
- istartswith,iendswith:匹配开头或结尾,大小写不敏感
- in:是否在某个list中
- gt,lt,gte,lte等比较操作
- year,month,day,week_day,hour,minute,seconde等时间操作
- isnull:是否为空
- 跨relationship的field查询,
#entry与blog是多对一的关系
Entry.objects.filter(blog__name='Beatles Blog')
Blog.objects.filter(entry__headline__contains='Lennon')
#entry与authors是多对多关系
Blog.objects.filter(entry__authors__name='Lennon')
Blog.objects.filter(entry__authors__name__isnull=True)
Blog.objects.filter(entry__authors__isnull=False,
entry__authors__name__isnull=True) 注意下面代码的区别
#返回的blog 同时满足参数中的两个条件
Blog.objects.filter(entry__headline__contains='Lennon',
entry__pub_date__year=2008)
#blog包含多个entry,只要其中有两个分别满足下面两个条件,就返回blog
Blog.objects.filter(entry__headline__contains='Lennon').filter(
entry__pub_date__year=2008)
- F class:用于获取model field的值
Q class:用于定义重用查询条件,Q objects可以使用&和|进行组合,这样会生成新的Q object,field的查询关键字都可以在Q object的参数中使用
Q(question__startswith='Who') | ~Q(pub_date__year=2005)
Poll.objects.get(
Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),
question__startswith='Who')
reporter = Reporters.objects.get(name='Tintin')
reporter.stories_filed += 1
reporter.save()
#与上面代码效果相同
reporter = Reporters.objects.filter(name='Tintin')
reporter.update(stories_filed=F('stories_filed') + 1)
#更新所有stories_field
Reporter.objects.all().update(stories_filed=F('stories_filed') + 1)
Entry.objects.filter(authors__name=F('blog__name'))
- 删除对象使用delete()方法,model和queryset都包含此方法用于删除单个或者多个对象。对于外键对象,如果定义时设置了on_delete参数为true,那么删除外键对象时会把指向该外键对象的对象也删除
e.delete()
Entry.objects.filter(pub_date__year=2005).delete()
Entry.objects.all().delete()
b = Blog.objects.get(pk=1)
# This will delete the Blog and all of its Entry objects.
b.delete()
- 复制对象:
- 简单情况
blog = Blog(name='My blog', tagline='Blogging is easy')
blog.save() # blog.pk == 1
# 设置pk为None
blog.pk = None
blog.save() # blog.pk == 2
- 继承类
class ThemeBlog(Blog):
theme = models.CharField(max_length=200)
django_blog = ThemeBlog(name='Django', tagline='Django is easy', theme='python')
django_blog.save() # django_blog.pk == 3
#需要设置id和pk为None
django_blog.pk = None
django_blog.id = None
django_blog.save() # django_blog.pk == 4
- 上面两种方式都不给related object赋值,赋值related object的代码如下:
entry = Entry.objects.all()[0] # some previous entry
old_authors = entry.authors.all()
entry.pk = None
entry.save()
entry.authors = old_authors # saves new many2many relations
|