- model对应数据库表,model的实例则对应表中的一条记录. 添加ForeignKey和ManyToManyField的field值
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()
Blog.objects.create(name='news Blog', tagline='All news.')
#create方法包含创建对象并save到数据库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:是否为空
- exact:精确匹配,默认使用
- 跨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