1.一个模型类代表数据库中的一个表,一个模型类的实例代表这个数据库表中的一条特定的记录。
2.管理器和查询集。
- 过滤器基于所给的参数限制查询的结果。查询集有可迭代和可切片的特点。
- 每个模型都至少有一个管理器,它默认命名为objects。管理器只可以通过模型的类访问,而不可以通过模型的实例访问,目的是为了强制区分“表级别”的操作和“记录级别”的操作。
>>>Blog.objects
<django.db.models.manager.Manager object at ...>
>>> b = Blog(name='Foo', tagline='Bar')
>>> b.objects
Traceback:
...
AttributeError: "Manager isn't accessible via Blog instances."
3.创建、更改,并保存一个实例
from blog.models import Blog b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.') b.save()
b.name = 'New name'
b.save()
注意:在调用b.save()时,Django才正真访问数据库。
也可以使用管理器的create方法,一步创建和保存。
p = Person.objects.create(first_name="Bruce", last_name="Springsteen")
- 更新ForeignKey 字段的方式和保存普通字段相同 —— 只要把一个正确类型的对象赋值给该字段。
- 更新ManyToManyField 的方式有一些不同 —— 需要使用字段的add()方法来增加关联关系的一条记录。为了在一条语句中,向ManyToManyField添加多条记录,可以在调用add()方法时传入多个参数
from blog.models import Author joe = Author.objects.create(name="Joe") entry.authors.add(joe)
可以使用update() 方法查询集中所有对象的某个字段都设置一个特定的值。
# Update all the headlines with pub_date in 2007. Entry.objects.filter(pub_date__year=2007).update(headline='Everything is the same')
4.获取对象(查询集方法的完整列表,请参见查询集API 参考https://docs.djangoproject.com/en/1.10/ref/models/querysets/。)
- 获取所有对象
all_blogs = Blog.objects.all()
all()方法返回包含数据库中所有对象的一个查询集。
- 可以使用filter(**kwargs),exclude(**kwargs)设置过滤条件,返回一个新的查询子集。
Entry.objects.filter(headline__startswith='What').exclude(pub_date__gte=datetime.date.today())
- 查询集都是独立的。
>>> q1 = Entry.objects.filter(headline__startswith="What") >>> q2 = q1.exclude(pub_date__gte=datetime.date.today()) >>> q3 = q1.filter(pub_date__gte=datetime.date.today())
- 查询集需要求值时,Django 才会真正运行这个查询。
- (中间是两个下划线)。
Entry.objects.filter(pub_date__lte='2006-01-01') Entry.objects.get(headline__exact="Man bites dog") Blog.objects.get(name__iexact="beatles blog") Entry.objects.get(headline__contains='Lennon')
大约有二十多种查询的类型。_id 后缀。
Entry.objects.filter(blog_id=4)
- 多表关联查询:只需使用关联的模型字段的名称,并使用双下划线分隔。
#from django.db import models #class Blog(models.Model): # name = models.CharField(max_length=100) #class Author(models.Model): # name = models.CharField(max_length=50) #class Entry(models.Model): # blog = models.ForeignKey(Blog) # authors = models.ManyToManyField(Author) Entry.objects.filter(blog__name='Beatles Blog')
若要引用一个“反向”的关系,只需要使用该模型的小写的名称。
Blog.objects.filter(entry__headline__contains='Lennon')
- 如果知道只有一个对象满足你的查询,可以使用管理器的get() 方法,它直接返回该对象:
one_blog = Blog.objects.get(pk=1)
如果没有结果满足查询,get() 将引发一个DoesNotExist 异常。MultipleObjectsReturned异常。
- 可以使用切片和索引限制查询集。
#切片
Blog.objects.all()[5:10]
Blog.objects.all()[:10:2]
#索引
Blog.objects.order_by('headline')[0]
-
其他常用的查询API包括:
- order_by:对查询结果排序。
- reverse:对查询结果反向排序。
- distinct:从返回结果中剔除重复记录。
- values:返回一个ValuesQuerySet —— QuerySet 的一个子类,迭代时返回字典而不是模型实例对象。
- values_list:与values() 类似,只是在迭代时返回的是元组而不是字典。
- count:返回在数据库中对应的 QuerySet.对象的个数。
- first,last,earliest,latest:返回QuerySet.对象的第一、最后、最早、最近的一条记录。
- exists:如果QuerySet 包含任何结果,则返回True,否则返回False。
- 聚合函数和分组函数:
-
>>> from django.db.models import Avg, Max, Min
>>> Book.objects.aggregate(average_price=Avg('price'), Max('price'), Min('price'))
{'average_price': 34.35, 'price__max': Decimal('81.20'), 'price__min': Decimal('12.99')}
-
- annotate()。
# Build an annotated queryset
>>> from django.db.models import Count
>>> q = Book.objects.annotate(num_authors=Count('authors'))
>>> q[0].num_authors
2
>>> q[1].num_authors
1
- 在聚合函数中指定聚合字段时,Django 允许你使用同样的 双下划线 表示关联关系;也同样可以用
-
NOT) 查询。
Poll.objects.get(
Q(question__startswith='Who'),
Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
)
- 比较对象:在后台,它会比较两个模型主键的值。
5.删除对象
方法将立即删除对象且没有返回值。
Entry.objects.filter(pub_date__year=2005).delete()
如果你确实想删除所有的对象,你必须明确地请求一个完全的查询集:
Entry.objects.all().delete()
6.复制对象
最简单的方法是,只需要将pk 设置为None。
blog = Blog(name='My blog', tagline='Blogging is easy') blog.save() # blog.pk == 1 blog.pk = None blog.save() # blog.pk == 2