Django中的__(双下划线)
在Django中,双下划线(__
)在查询操作中有着非常重要的作用,尤其是与 查询过滤(filter) 和 字段查找(lookup) 相关的操作。它可以让你进行跨字段查询、字段的精确查找、以及其他复杂的查询操作。
1. 基本用法:字段查找(Lookup)
Django 使用双下划线(__)来表示各种字段查找操作,它通常用于 filter()
、exclude()
、get()
等查询方法中。
比如:
# 例如,假设有如下的模型:
class Product(models.Model):
name = models.CharField(max_length=100)
price = models.DecimalField(max_digits=10, decimal_places=2)
created_at = models.DateTimeField(auto_now_add=True)
category = models.ForeignKey('Category', on_delete=models.CASCADE)
# 查询价格大于100的所有产品
products = Product.objects.filter(price__gt=100)
# 查询所有名称包含"phone"的产品
products = Product.objects.filter(name__icontains="phone")
# 查询创建日期在某个范围内的产品
products = Product.objects.filter(created_at__gte='2024-01-01', created_at__lt='2024-12-31')
# 查询与某一类别相关联的所有产品
products = Product.objects.filter(category__name="Electronics")
-
第一个查询返回价格大于100的所有产品。
-
第二个查询返回所有名称包含 "phone" 的产品(不区分大小写)。
-
第三个查询返回创建日期在2024年1月1日到2024年12月31日之间的所有产品。
-
第四个查询返回所有属于类别 "Electronics" 的产品。
每个查询返回的都是一个 QuerySet,即一组符合查询条件的模型实例,允许你进一步操作和迭代这些结果
2. 字段查找的种类
__
后面跟的部分是查找类型(lookup),它指示了如何进行过滤、查询或者比较。Django 提供了多种字段查找类型:
(1) 精确匹配
fieldname__exact
: 查找精确匹配的字段值
Product.objects.filter(name__exact="iPhone")
查询名称正好是 iPhone 的产品。
(2) 大小写不敏感匹配
fieldname__iexact
: 查找不区分大小写的精确匹配。
Product.objects.filter(name__iexact="iphone")
查询名称为 iphone 或者 IPHONE(不区分大小写)等的产品。
(3) 包含关系
-
fieldname__contains
: 查找字段值中包含某个字符串。Product.objects.filter(name__contains="phone")
查询名称中包含 phone 的所有产品。
-
fieldname__icontains
: 不区分大小写的包含查询。Product.objects.filter(name__icontains="phone")
(4) 开头和结尾匹配
-
fieldname__startswith
: 查找以指定字符串开头的字段值。Product.objects.filter(name__startswith="iP")
-
fieldname__istartswith
: 不区分大小写的开头匹配。Product.objects.filter(name__istartswith="ip")
-
fieldname__endswith
: 查找以指定字符串结尾的字段值。Product.objects.filter(name__endswith="Phone")
-
fieldname__iendswith
: 不区分大小写的结尾匹配。Product.objects.filter(name__iendswith="phone")
(5) 数值比较
-
fieldname__gt
: 大于指定值(Greater Than)。Product.objects.filter(price__gt=100)
-
fieldname__gte
: 大于等于指定值(Greater Than or Equal To)Product.objects.filter(price__gte=100)
-
fieldname__lt
: 小于指定值(Less Than)。Product.objects.filter(price__lt=100)
-
fieldname__lte
: 小于等于指定值(Less Than or Equal To)。Product.objects.filter(price__lte=100)
-
fieldname__exact
: 查找完全等于某个值(精确匹配)。Product.objects.filter(price__exact=200)
(6) 范围查找
-
fieldname__range
: 查找某个字段值在指定范围内的记录。Product.objects.filter(price__range=(100, 500))
该范围是 闭区间,意味着 包括 范围的两端值。
(7) 日期和时间查找
-
fieldname__date
: 查找某日期字段的日期部分。Product.objects.filter(created_at__date="2024-01-01")
-
fieldname__year
,fieldname__month
,fieldname__day
:按年、月、日查找。Product.objects.filter(created_at__year=2024)
-
fieldname__week_day:
查找某日期字段的星期几(1表示星期一,7表示星期天)。Product.objects.filter(created_at__week_day=2) # 查找创建日期是星期二的产品
3. 关系查找:跨越外键关系
Django 的双下划线还支持跨越模型之间的外键关系进行查询。你可以使用双下划线来访问外键模型的字段。
比如:
class Category(models.Model):
name = models.CharField(max_length=100)
class Product(models.Model):
name = models.CharField(max_length=100)
price = models.DecimalField(max_digits=10, decimal_places=2)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
# 查找某一类别下所有价格大于100的产品
products = Product.objects.filter(category__name="Electronics", price__gt=100)
这里使用了 category__name
来访问与 Product 相关联的 Category 模型中的 name 字段。
4. 总结:双下划线(__)的作用
-
字段查找:双下划线用于在查询中执行各种条件过滤操作,比如精确匹配、模糊匹配、范围查找等。
-
跨模型查询:通过
__
,你可以跨越模型之间的外键关系来查询相关字段的值。 -
日期时间查找:它也可以用于对日期字段的年、月、日等进行查询。
Django 的双下划线使得查询功能非常强大,可以实现复杂的查询条件和跨模型的数据访问。