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 的双下划线使得查询功能非常强大,可以实现复杂的查询条件和跨模型的数据访问。

posted @ 2024-11-21 19:27  hisun9  阅读(3)  评论(0编辑  收藏  举报