Django使用笔记(三)

本文讲解Django在数据库方面的基本使用。

基本查询

有时候,我们查询数据时并不需要该数据的全部字段,这个时候可以使用valuesvalues_list,它们的区别在于:

  • values方法可以获取指定字段的字典列表
  • values_list方法获取指定字段的元组列表,当加上参数flat=True时,可以获取指定字段的值列表

使用示例:

YourModel.objects.values('field1', 'field2')
YourModel.objects.values_list('field', flat=True)

当对象与另一个对象存在一对一的关系时,如果想同时查找到关联对象,可以使用select_related(*fields)方法。
下面是官方文档的说明:

# Hits the database.
e = Entry.objects.get(id=5)

# Hits the database again to get the related Blog object.
b = e.blog

# Hits the database.
e = Entry.objects.select_related('blog').get(id=5)

# Doesn't hit the database, because e.blog has been prepopulated
# in the previous query.
b = e.blog

filter() 和 select_related() 的顺序不重要。下面两个语句是等价的。

Entry.objects.filter(pub_date__gt=timezone.now()).select_related('blog')
Entry.objects.select_related('blog').filter(pub_date__gt=timezone.now())

F() 对象

一个 F() 对象表示一个模型属性的值。
不使用F()对象时,可能是这样:

reporter = Reporters.objects.get(name='Tintin')
reporter.stories_filed += 1
reporter.save()

但是使用F()对象后,就变成:

from django.db.models import F
reporter = Reporters.objects.get(name='Tintin')
reporter.stories_filed = F('stories_filed') + 1
reporter.save()

这种方法是在数据库层面操作的,因此不需要把stories_filed的值载入内存再进行运算。
使用这种方法后,要想获得保存后的新值,需重新载入:

reporter.refresh_from_db()

除了应用在单个实体上,F() 也可以用在多个实体上:

Reporter.objects.all().update(stories_filed=F('stories_filed') + 1)

Q对象

使用django的Q对象可以做一些复杂查询。例如,下面的语句表示LIKE查询:

from django.db.models import Q
Q(question__startswith='What')

Q对象之间可以使用 & 和 | 进行组合。同时,当Q对象前面有 ~ 符号时,表示否定。
查询函数可以同时使用Q对象和关键字参数,但是Q对象必须在关键字参数前面。
比如,下面做法是正确的:

Poll.objects.get(
    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),
    question__startswith='Who',
)

但是下面的代码就不正确了:

# INVALID QUERY
Poll.objects.get(
	question__startswith='Who',
	Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
)

自定义SQL

Django可以使用如下方法执行自定义SQL:

Manager.raw(raw_query, params=None, translations=None)

这个方法执行一个原始SQL(raw_query),返回一个RawQuerySet实例。
raw方法自动映射查询中的字段到模型字段,因此查询中的字段的顺序是无所谓的。
你也可以执行模型中没有包含的字段的查询,查询依然可以成功,并且可以访问到该字段,如下:

people = Person.objects.raw('SELECT *, age(birth_date) AS age FROM myapp_person')
for p in people:
    print("%s is %s." % (p.first_name, p.age))

raw传递参数的方式如下:

lname = 'Doe'
Person.objects.raw('SELECT * FROM myapp_person WHERE last_name = %s', [lname])

分页查询

要进行分页查询时,可以使用django.core.paginator.Paginator,如下:

models = Model.objects.all()
paginator = Paginator(models, pagesize)
result = paginator.page(page) # page从1开始,代表第几页

paginator还有其他一些属性,比如paginator.count表示总记录数,paginator.num_pages表示总页数
要向客户端返回result的json结果时,可以使用如下方式:

from django.core import serializers
from django.http import JsonResponse
import json
response = {}
services = SystemService.objects.all()
paginator = Paginator(services, pageSize)
response['total'] = paginator.count
try:
    result = paginator.page(page)
except PageNotAnInteger:
    result = paginator.page(1)
except EmptyPage:
    result = paginator.page(paginator.num_pages)
response['result'] = json.loads(serializers.serialize("json", result.object_list))
return JsonResponse(response)

实体更新

Django更新一个model的做法非常简单,首先将要更新的属性及其新值写在一个dict中,然后调用model.__dict__.update(**data),最后调用save方法保存到数据库中即可,示例如下:

data = {
	'name': 'test'
}
old = MyModel.objects.get(id=1)
old.__dict__.update(**data)
old.save()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值