Django ORM查询

Django ORM查询

在本教程中,我们将对Django ORM查询进行全面讨论,以及如何使用它们来操作数据。

Django ORM是Django的最佳工具之一,对于执行与数据库相关的任务起着非常重要的作用。它以一种大多数据库无关的方式提供与数据库的抽象。

Django ORM包括易于使用的抽象。它保持 “简单的事情易做,困难的事情可行。”

在这里,我们将详细解释每个ORM查询,并查看它们关联的SQL查询。

使用模型在数据库中创建表

首先,我们将使用Django模型创建一个包含一些数据的示例数据库,并在该数据库上运行查询。

model.py

# Create your models here.

class Student(models.Model):
    username = models.CharField(max_length=20)
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    mobile = models.CharField(max_length=10)
    email = models.EmailField()

    def __str__(self):
        return "%s %s" % (self.first_name, self.last_name)

然后执行以下命令。

python manage.py makemigrations
python manage.py migrate

我们准备运行这个查询。

如何从表(Model)中获取所有记录

我们有一个叫做 Student 的模型。 为了从模型中获取所有记录,我们将使用 Student.objects.all() 。 为此,请打开Django shell运行查询。

>>> from sampleapp.models import Student
>>> queryset = Student.objects.all()
>>> queryset
, , , , , ]>

你可能会想知道 Django ORM 是如何执行我们的查询或者我们编写的代码对应的查询。获取SQL查询相当简单,我们只需使用 str() 并传递 查询对象 和查询即可。

相应的SQL查询

>>> str(queryset.query)
'SELECT "sampleapp_student"."id", "sampleapp_student"."username", "sampleapp_student"."first_name", "sampleapp_student"."last_name", "sampleapp_student"."mobile", "sampleapp_student"."email" FROM "sampleapp_student"'

Django ORM查询

如何向表(模型)中添加记录

我们将使用 Student.objects.create() 函数,并将字段及其值作为参数传递。让我们看下面的示例。

>>> queryset = Student.objects.create(username = 'rahul20', first_name = 'Rahul', last_name = 'Shakya', mobile = '77777', email = 'rahul@gmail.com')
>>> queryset.save()

请注意,我们需要在查询对象上使用 .save() 方法将新创建的记录保存在表中,否则它将不会显示在数据库中。

从查询集中检索单个对象

假设我们需要从查询集中获取特定对象以匹配结果。我们可以使用 get() 方法来完成这个操作。get()方法直接返回单个对象。让我们看下面的例子。

示例-

>>> from sampleapp.models import Student
>>> queryset = Student.objects.get(pk = 1)
>>> queryset

示例 – 2

>>> queryset = Student.objects.get(mobile = 22222) 
>>> queryset

正如我们在两个示例中看到的那样,我们得到的是单个对象而不是单个对象的查询集。如果没有结果匹配查询, get() 将引发 DoesNotExist 异常。另一方面,如果有多个字段匹配,它将引发 MultipleObjectReturned 异常,这是模型类本身的属性。

筛选记录

在前面的示例中,由 all() 返回的 QuerySet 描述了数据库表中的所有记录。但是有时候,我们需要选择完整对象集的子集,并且可以通过添加 filter 条件来实现。

在下面的示例中,我们将获取以 R 开头的姓氏的数据。

>>> queryset = Student.objects.filter(first_name__startswith = 'R')
>>> queryset
, ]>
>>> str(queryset.query)
'SELECT "sampleapp_student"."id", "sampleapp_student"."username", "sampleapp_student"."first_name", "sampleapp_student"."last_name", "sampleapp_student"."mobile", "sampleapp_student"."email" FROM "sampleapp_student" WHERE "sampleapp_student"."first_name" LIKE R% ESCAPE \'\\\''

注意 – get()方法和filter()方法的区别在于,filter()方法返回对象的查询集,而get()方法返回单个对象。

使用exclude()方法

它返回一个新的 查询集 ,其中包含不匹配给定查找参数的对象。换句话说,它根据查找条件排除了记录。让我们理解以下示例。

>>> queryset = Student.objects.exclude(first_name__startswith = 'R') 
>>> queryset

输出结果:

, , , , ]>

如何在Django ORM中进行OR查询

当我们需要使用两个或多个条件进行记录过滤时,会执行OR操作。在下面的示例中,我们将获取名字以’A’开头且姓以’M’开头的学生。

Django允许我们有两种方法来实现这一点。

  • queryset_1 | queryset_2
  • filter(Q( ) | Q(
>>> queryset = Student.objects.filter(first_name__startswith = 'R') | Student.objects.filter(last_name__startswith = 'S')   
>>> queryset
, , , , ]>

我们获取名字以 ‘A’ 开头、姓以 ‘S’ 开头的学生详细信息。

以下是相应的OR操作符的SQL查询。

>>> str(queryset.query) 
'SELECT "sampleapp_student"."id", "sampleapp_student"."username", "sampleapp_student"."first_name", "sampleapp_student"."last_name", "sampleapp_student"."mobile", "sampleapp_student"."email" FROM "sampleapp_student" WHERE ("sampleapp_student"."first_name" LIKE R% ESCAPE \'\\\' OR "sampleapp_student"."last_name" LIKE S% ESCAPE \'\\\')'

如何在Django ORM中进行AND查询

当我们需要与两个或多个条件匹配的记录时,需要进行AND操作。在下面的例子中,我们将获得名字以’P’开头且姓以’S’开头的学生。

Django允许我们以三种方式实现这一点:

  • queryset_1 & queryset_2
  • filter( , )
  • filter(Q(condition_1) & Q(condition_2))
>>> queryset = Student.objects.filter(first_name__startswith = 'P') & Student.objects.filter(last_name__startswith = 'S') 
>>> queryset
]>

只有一个对象满足给定的条件。

我们还可以使用以下查询。

queryset2 = User.objects.filter( first_name__startswith='A', last_name__startswith='S' )

或者

queryset3 = User.objects.filter(Q(first_name__startswith='R') & Q(last_name__startswith='D') )

所有查询将产生相同的结果。

一次性创建多个对象

有时我们想要一次性创建多个对象。假设我们想要立即创建新对象,而不想对数据库运行多个查询。Django ORM提供了 bulk_create 来一次性创建多个对象。

>>> Student.objects.all().count()
7

让我们一次查询中创建多条记录。

Student.objects.bulk_create([Student(first_name = 'Jai', last_name = 'Shah', mobile = '88888', email = 'shah@reddif.com'),Student(first_name = 'Tarak', last_name = 'Mehta', mobile = '9999', email = 'tarak@reddif.com'), Student(first_name = 'SuryaKumar', last_name = 'Yadav', mobile = '00000', email = 'yadav@reddif.com')])
[, , ]

现在,我们的数据库表将会更新。bulk_create接受一个未保存对象的列表。

>>> Student.objects.all().count()
10

限制查询集

我们可以使用Python的 列表切片 语法来限制查询集的数量。这相当于SQL中的 LIMITOFFSET 子句的操作。让我们看一下下面的查询。

>>> Student.objects.all()[:4]
, , , ]>

以下查询将返回 第一个 记录到 第五个 记录。

>>> Student.objects.all()[1:6]   
, , , , ]>

不支持负索引。但是,我们可以在QuerySets中使用 步长

>>> Student.objects.all()[:10:2]   
[, , , , ]

要获取单个记录,我们可以执行以下操作。

>>> Student.objects.all()[0]       

如何按升序或降序对QuerySets进行排序

Django提供了 order_by 方法来对查询结果进行排序。该方法接受 字段名 作为参数,用于对结果进行升序或降序排序。让我们看下面的例子。

示例- 升序排列

>>> from sampleapp.models import Student
>>> Student.objects.all().order_by('mobile')    
, , , , , , , , , ]>

对于降序排列,我们将在查询字段之前不使用“-”。

>>> from sampleapp.models import Student  
>>> Student.objects.all().order_by('-mobile')
, , , , , , , , , ]>

我们还可以在 order_by 函数中传递多个字段。

>>> Student.objects.all().order_by('first_name','-mobile') 
, , , , , , , , , ]>

如何在相关模型上按照外键排序

现在,我们将学习如何在关联模型中对数据进行排序。我们创建了另一个模型叫做 Teacher ,它是 Student 模型的关联模型。

模型

class Teacher(models.Model):
    teacher_name = models.CharField(max_length=200)

    def __str__(self):
        return f'{self.teacher_name}'

class Student(models.Model):
    username = models.CharField(max_length=20)
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    mobile = models.CharField(max_length=10)
    email = models.EmailField()
    teacher_name = models.ForeignKey(Teacher, blank = True, null = True, on_delete= models.CASCADE)

我们已经添加了教师的姓名,每个教师与学生关联。现在我们想要按照每个 教师姓名 内的学生 对学生进行排序 。我们可以按照以下方式操作。

>>> Student.objects.all().order_by('teacher__id', 'first_name')     
, , , , , , , , , ]>

重要的字段查找

查询字段查找就是指定与SQL中的WHERE子句相同的条件。它们被作为关键字参数传递给QuerySet方法,例如 filter()exclude()get()

示例 –

Student.objects.filter(first_name__startswith = 'Ritesh') 
]>

这与以下的SQL查询相同

Select * from Student where first_name = "Ritesh"

让我们了解一些重要的查找。

  • exact

根据搜索返回精确结果。

>>> Student.objects.get(first_name__exact = 'Arpita')         

在双下划线之后应使用Lookup: __ 。我们可以使用不区分大小写的版本,称为 iexact

  • contains

它用于区分大小写的测试。让我们看下面的例子。

>>> from sampleapp.models import Student
>>> Student.objects.filter(last_name__contains = 'Shar')     
, , ]>

如果我们将SQL查询翻译成中文,它会看起来像下面这样。

SELECT ... WHERE last_name LIKE '%Shar%';

也有一种叫做 icontains 的案例激励版本。

如何在Django中执行连接操作

SQL连接在两个或多个表之间基于共同字段结合数据或行。我们可以以多种方式执行连接操作。让我们理解以下示例。

>>> q = Student.objects.select_related('teacher')
>>>q
, , , , , , , , , ]>
>>>print(q.query)
SELECT "sampleapp_student"."id", "sampleapp_student"."username", "sampleapp_student"."first_name", "sampleapp_student"."last_name", "sampleapp_student"."mobile", "sampleapp_student"."email", "sampleapp_student"."teacher_id", "sampleapp_teacher"."id", "sampleapp_teacher"."teacher_name" FROM "sampleapp_student" LEFT OUTER JOIN "sampleapp_teacher" ON ("sampleapp_student"."teacher_id" = "sampleapp_teacher"."id")

如何在Django ORM中分组记录

Django ORM通过使用聚合函数(如Max、Min、Avg和Sum)提供分组功能。有时我们需要从对象中获取聚合值。让我们理解以下示例。

>>> from django.db.models import Avg, Max, Min, Sum, Count
>>> Student.objects.all().aggregate(Avg('id'))
{'id__avg': 5.5}
>>> Student.objects.all().aggregate(Min('id'))  
{'id__min': 1}
>>> Student.objects.all().aggregate(Max('id')) 
{'id__max': 10}
>>> Student.objects.all().aggregate(Sum('id')) 
{'id__sum': 55}

如何使用Django ORM执行类似于truncate的操作

在SQL中,truncate的意思是清除表中的数据以供将来使用。Django没有提供内置的方法来截断表,但我们可以使用 delete() 方法来获得类似的结果。让我们来理解以下示例。

>>> Student.objects.all().count()
10
>>> Student.objects.all().delete()
(10, {'sampleapp.Student': 10})
>>> Student.objects.all().count()
0
>>> Student.objects.all()     

如果要删除单个对象实例,您需要在该模型的个别实例上调用 delete() 方法。我们已经调用了模型上的 delete() 方法,所以它删除了整个数据。

如何获取数据的并集

并集意味着获取在两个查询集中都存在的记录。让我们看看如何做到这一点。

>>> q1 = Student.objects.filter(id__gte = 15)  
>>> q1
, ]>
>>> q2 = Student.objects.filter(id__lte = 15)  
>>> q2
, , , , ]>
>>> q1.union(q2)
, , , , , ]>

什么是null=True和blank=True的区别

在Django中,我们经常使用null和blank,默认情况下它们的值为False。这两个值都用于字段级别,在我们想要保持字段为null或空白的情况下使用。这两个值似乎相似,但在使用上有所不同。

如果 null=True 表示字段值被设为NULL,即没有数据。它基本上是用于数据库列值。

date = models.DateTimeField(null=True)

空格=True指定字段在表单中是否为必填项。

title = models.CharField(blank=True) // title can be kept blank. In the database ("") will be stored.

如果我们设置了 null=True blank=True ,这意味着该字段在任何情况下都是可选的。

teacher = models.ForeignKey(null=True, blank=True) // The exception is CharFields() and TextFields(), which in Django are never saved as ?→NULL. Blank values are stored in the DB as an empty string ('').

结论

在这个教程中,我们学习了一些重要的ORM查询。Django ORM是一个强大的工具,也是Django的一个关键支柱。Django自带名为SQLite的内置数据库。我们描述了ORM查询,其与SQL查询具有相同的作用。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程