django数据库操作

django数据库操作

    • 插入语句
    • 查询操作
      • 查询集
      • all(),count(),get()
      • 过滤器 filter exclude
        • 根据日期的某些值查询
        • 字段查询
      • 跨表查询(跨越关系查询)
      • F对象
      • Q对象
      • 一对多查询
  • 在多方定义外键时,如果指定了related_name,则可以通过related_name查询
      • 聚合
    • 比较对象
    • 删除对象
    • 更新
    • 保存ForeignKey和ManyToManyField字段
    • 事务

插入语句

  • save 需要调用save才能写入数据库
q = Question(question_text="what's your name?",pub_date=date)
q.save()
  • create 不需要调用sace
Question.objects.create(question_text="what's your name?",pub_date=date)

查询操作

查询集

调用过滤器方法时,django会返回查询集,查询及有两大特性

  • 惰性执行
    创建查询集不会访问数据库,直到调用数据时,才会访问数据库,调用数据的情况包括迭代、序列化、与if合用

  • 缓存
    使用同一个查询集,第一次使用时会发生数据库的查询,然后Django会把结果缓存下来,再次使用这个查询集时会使用缓存的数据,减少了数据库的查询次数。

    • 要正确使用缓存,例如,以下内容将创建两个QuerySets,从而导致数据库负载加倍

      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.
      
  • 只支持简单切片[0:5],[5:10],不支持step,不支持负数切片,限制所述查询集使用阵列切片或索引不会填充缓存

queryset = Entry.objects.all()
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

以下是一些其他操作的示例,这些操作将导致整个查询集被评估,从而填充缓存:

[entry for entry in queryset]
bool(queryset)
entry in queryset
list(queryset)

all(),count(),get()

  • all():检索所有对象,MyModel.objects.all() 返回查询集
  • count():检索对象数量,MyModel.objects.count() 返回整型
  • get()返回单个对象,但是与filter有区别,filter在没有查询到结果时会返回一个空的查询集,而get会抛出DoesNotExist异常。当查询结果大于1时,会抛出MultipleObjectsReturned异常。只适用于单个查询,一般时通过主键。

过滤器 filter exclude

在查询集以及管理器上可以调用过滤器

根据日期的某些值查询

# 可选 year month day hour minute second
User.objects.filter(birthday__year=2010)

字段查询

基本查找关键字参数采用表单field__lookuptype=value

lookuptype instruction mean
lte <= less then or equal
gte >= greater then or equal
id,pk id id
exact = 完全相等
iexact = 不区分大小写的相等
contains 包含 包含,类似于 sql 中 like “%xxx%”
startswith, endswith 开头,结尾 istartswith, iendswith,此为不区分大小写的版本
in 范围查询

跨表查询(跨越关系查询)

官方文档
Django提供了一种强大而直观的方式来“跟踪”查找中的关系JOIN,在后台自动为您处理SQL 。要跨越关系,只需使用跨模型的相关字段的字段名称,用双下划线分隔,直到到达所需的字段。

Order.objects.filter(user__name='Lisa')

#如果您要跨多个关系进行过滤,并且其中一个中间模型没有满足过滤条件的值,Django会将其视为存在空(所有值都是NULL),但有效,对象存在。所有这些意味着不会引发任何错误。例如,在此过滤器中:

Blog.objects.filter(entry__headline__contains='Lennon')

(如果存在相关Author模型),如果没有author 与条目相关联,则将其视为没有name 附加,而不是因为缺失而引发错误author。通常这正是你想要发生的事情。唯一可能令人困惑的情况是你正在使用它isnull。从而:

Blog.objects.filter(entry__authors__name__isnull=True)

将返回Blog有一个空的对象name上author,以及那些具有空author的entry。如果你不想要那些后面的对象,你可以写:

Blog.objects.filter(entry__authors__isnull=False, entry__authors__name__isnull=True)

F对象

在到目前为止给出的例子中,我们构造了过滤器,用于比较模型字段的值和常量。但是,如果要将模型字段的值与同一模型上的另一个字段进行比较,该怎么办?

Django 允许进行这样的比较。作为查询中模型字段的引用的实例。然后,可以在查询过滤器中使用这些引用来比较同一模型实例上的两个不同字段的值。F expressionsF()

from django.db.models import F # 导入F对象
# 查询评论量大于点击量的所有对象
Question.objects.filter(comments__gt=F('clicks'))

Q对象

filter过滤时,会将条件按照and连接在一起,如果需要使用or,则需要用到django提供的Q对象。
如下

Q(question__startswith='Who') | Q(question__startswith='What')
这相当于以下SQL WHERE子句:
WHERE question LIKE 'Who%' OR question LIKE 'What%'

~Q(pub_date__year=2005) # 表示非
如果同时使用了关键字参数与Q对象,需要将Q对象放在查询语句前面
下面这句将抛出异常:SyntaxError: positional argument follows keyword argument
Question.objects.filter(question_text__startswith=“w”,Q(id=1)|Q(id=4))
正确的写法为:
Question.objects.filter(Q(id=1)|Q(id=4),question_text__startswith=“w”)

一对多查询

在一方查询与其存在关系的多方

Question.objects.get(pk=1).choice_set.all()

在多方定义外键时,如果指定了related_name,则可以通过related_name查询

Question.objects.get(pk=1).choices.all()

在多方查询一方,直接调用该属性即可

Choice.objects.get(pk=1).question

除了QuerySet上面“检索对象”中定义的方法之外,还有用于处理相关对象集的其他方法。每个的概要如下,完整的细节可以在相关的对象参考中找到。ForeignKey Manager

add(obj1, obj2, …)
将特定的模型对象加入关联对象集合。
create(**kwargs)
创建一个新对象,保存它并将其放入相关的对象集中。返回新创建的对象。
remove(obj1, obj2, …)
从相关对象集中删除指定的模型对象。
clear()
从相关对象集中删除所有对象。
set(objs)
替换相关对象集。

聚合

# 所有书的平均价格
from django.db.models import Avg
Book.objects.all().aggregate(Avg(‘price’))
# 所有书的最高价格
from django.db.models import Max
Book.objects.all().aggregate(Max(‘price’))
# 最高价格与平均价格的差值
Book.objects.all().aggregate(Max(‘price’,output_field=FloatField())-Avg(‘price’))

annotate
用于关系查询时的聚合

比较对象

两个模型对象的进行 == 比较,其实时对其主键的比较

some_entry == other_entry
some_entry.id == other_entry.id

删除对象

object.delect()
queryset.delect()#查询集调用delete,批量删除

更新

obj.name = “xxx”
obj.save()
or obj.update(name=“xxx”)

保存ForeignKey和ManyToManyField字段

# 多对一
from blog.models import Blog, Entry
>>> entry = Entry.objects.get(pk=1)
cheese_blog = Blog.objects.get(name="Cheddar Talk")
entry.blog = cheese_blog
entry.save()
# 多对多略有不同,使用add()
john = Author.objects.create(name="John")
paul = Author.objects.create(name="Paul")
george = Author.objects.create(name="George")
ringo = Author.objects.create(name="Ringo")
entry.authors.add(john, paul, george, ringo)

事务

官方文档

你可能感兴趣的:(web开发技术,django)