【django查询】模糊查询

常用模糊查询的方法

queryset中支持链式操作

book=Book.objects.all().order_by('-nid').first()

只要返回的是queryset对象就可以调用其他的方法,直到返回的是对象本身

模糊查询常用的操作

大于、大于等于:

__gt 大于>
__gte 大于等于>=

Student.objects.filter(age__gt=10) // 查询年龄大于10岁的学生
Student.objects.filter(age__gte=10)// 查询年龄大于等于10岁的学生

特别注意:这里的下划线是双下划线,下面将介绍的也都是双下划线。
小于、小于等于:

__lt小于<
__lte 小于等于<=

Student.objects.filter(age__lt=10) // 查询年龄小于10岁的学生
Student.objects.filter(age__lte=10)// 查询年龄小于等于10岁的学生

like:

__exact 精确等于 like ‘aaa’
__iexact 精确等于 忽略大小写 ilike ‘aaa’
__contains 包含 like ‘%aaa%’
__icontains 包含,忽略大小写 ilike ‘%aaa%’,但是对于sqlite来说,contains的作用效果等同于icontains。

in:

__in

查询年龄在某一范围的学生
Student.objects.filter(age__in=[10, 20, 30])

is null / is not null:

__isnull判空

Student.objects.filter(name__isnull=True) // 查询用户名为空的学生
Student.objects.filter(name__isnull=False)// 查询用户名不为空的学生
不等于/不包含于:

Student.objects.filter().excute(age=10) // 查询年龄不为10的学生
Student.objects.filter().excute(age__in=[10, 20]) // 查询年龄不在 [10, 20] 的学生
其他常用模糊查询:

__startswith 以…开头
__istartswith 以…开头 忽略大小写
__endswith 以…结尾
__iendswith 以…结尾,忽略大小写
__range 在…范围内
__year 日期字段的年份
__month 日期字段的月份
__day 日期字段的日

Book.objects.filter(create_time__year=2019, create_time__month=4).all()

如果是mysql数据库settings里面修改 USE_TZ = False

多表连接查询:

 class A(models.Model):
    name = models.CharField(u'名称')
 class B(models.Model):
    aa = models.ForeignKey(A)

B.objects.filter(aa__name__contains='searchtitle') #查询B表中外键aa所对应的表中字段name包含searchtitle的B表对象

查询API

 all():                  查询所有结果
  
 filter(**kwargs):       它包含了与所给筛选条件相匹配的对象
  
 get(**kwargs):          返回与所给筛选条件相匹配的对象,返回结果有且只有一个,
                            如果符合筛选条件的对象超过一个或者没有都会抛出错误。
  
 exclude(**kwargs):      它包含了与所给筛选条件不匹配的对象
 
 order_by(*field):       对查询结果排序  用法:order_by('-price')        DESC 降序
  
 reverse():              对查询结果反向排序
  
 count():                返回数据库中匹配查询(QuerySet)的对象数量。
  
 first():                返回第一条记录
  
 last():                返回最后一条记录
  
 exists():              如果QuerySet包含数据,就返回True,否则返回False         相当于limit 1(用途查询这个表中是否有值)
 
 values(*field):        用法:Book.objects.all.values('title','price')  返回值是<queryset[{'title':'aa','pirce':12},{}]
 
 values_list(*field):   用法:Book.objects.all.values_list('title','price')  返回值是<queryset[('aa',12),('bb',33)]

 distinct():            从返回结果中剔除重复纪录  用法:Book.objects.all.values('title','price').distinct()   
                            错误用法 Book.objects.all.distinct()  因为id不相同,其他相同,无法去重 

查询案例

比如要分组查询
select primary_industry, count(*) as num from tonghsquotes_stockcompanyinfo a GROUP BY a.primary_industry ORDER BY num desc;

用orm实现
StockCompanyInfo.objects.all().values('primary_industry').annotate(num=Count('*')).order_by('-num')

<think>我们已知的Django模糊查询方法主要包含在filter()函数中,通过字段查询表达式实现。根据引用内容,有两个主要的表达式:contains和icontains。1.contains:大小写敏感模糊查询,生成的SQL语句使用LIKEBINARY,区分大小写。2.icontains:大小写不敏感模糊查询,生成的SQL语句使用LIKE,不区分大小写。另外,我们还可以通过其他字段查询表达式实现类似功能,例如startswith(以...开头)、endswith(以...结尾)等。下面,我将详细介绍如何在Django中实现模糊查询:###1.contains和icontains的基本用法假设我们有一个模型`Book`,它有一个`title`字段,我们想查询标题中包含特定字符串的书籍。```python#大小写敏感查询#查询标题中包含'django'(区分大小写)的书籍books=Book.objects.filter(title__contains='django')#大小写不敏感查询#查询标题中包含'django'(不区分大小写)的书籍books=Book.objects.filter(title__icontains='django')```###2.其他模糊查询表达式-`startswith`:以指定字符串开头(区分大小写)-`istartswith`:以指定字符串开头(不区分大小写)-`endswith`:以指定字符串结尾(区分大小写)-`iendswith`:以指定字符串结尾(不区分大小写)例如:```python#查询以'Python'开头的书籍(区分大小写)Book.objects.filter(title__startswith='Python')#查询以'Python'开头的书籍(不区分大小写)Book.objects.filter(title__istartswith='Python')```###3.在关系字段上的模糊查询如果有一个外键关系,比如模型`B`有一个外键`aa`指向模型`A`,而模型`A`有一个`name`字段,那么我们可以使用双下划线进行跨表查询。```python#查询B表中外键aa所对应的A表中字段name包含'searchtitle'的B表对象(大小写敏感)B.objects.filter(aa__name__contains='searchtitle')```###4.模糊查询的链式操作我们可以将多个条件组合在一起,例如:```python#查询标题中包含'django'且价格大于50的书籍(大小写不敏感)Book.objects.filter(title__icontains='django',price__gt=50)```###5.模糊查询的排除如果要排除满足条件的记录,可以使用`exclude()`方法。```python#排除标题中包含'django'的书籍Book.objects.exclude(title__icontains='django')```###注意事项-使用模糊查询时,特别是包含操作,会对数据库造成一定的性能负担,尤其是在大数据表上,因此建议建立合适的索引(虽然DjangoORM不会自动为这些字段创建索引)。-大小写敏感查询(contains)在MySQL中依赖于列的排序规则(collation)。如果列的排序规则是大小写敏感的(如utf8_bin),则有效;如果是不敏感的(如utf8_general_ci),则即使使用contains也可能不区分大小写。因此,在使用时需注意数据库设置。下面是一个实际应用的例子:假设我们有学生模型(Student),我们想根据用户输入的搜索条件(可能是大小写混合)来查询学生姓名中包含该条件的学生。```pythondefstudent_search(request):ifrequest.method=='POST':search_term=request.POST.get('search','')#使用icontains进行不区分大小写的模糊查询students=Student.objects.filter(name__icontains=search_term)returnrender(request,'search_results.html',{'students':students})#其他处理...```通过上述方法,我们可以轻松在Django中实现模糊查询功能。§§相关问题§§1.如何在Django中实现多字段的模糊查询?2.如何优化Django中的模糊查询性能?3.Django模糊查询时,数据库索引如何设置?</think> ### Django 模糊查询实现方法详解 在 Django 中实现模糊查询主要通过 ORM 的**字段查找表达式**完成,核心方法是结合 `filter()` 和特殊查询表达式: #### 1. 基础模糊查询表达式 - **`contains`**:大小写敏感查询 ```python # 查询 name 字段包含 "search" 的记录(区分大小写) Model.objects.filter(name__contains='search') ``` → 生成 SQL:`WHERE name LIKE BINARY '%search%'` - **`icontains`**:大小写**不**敏感查询 ```python # 查询 name 字段包含 "search" 的记录(不区分大小写) Model.objects.filter(name__icontains='search') ``` → 生成 SQL:`WHERE name LIKE '%search%'` [^1][^2] #### 2. 其他常用模糊表达式 - **开头匹配**: ```python Model.objects.filter(name__startswith='prefix') # 大小写敏感 Model.objects.filter(name__istartswith='prefix') # 大小写不敏感 ``` - **结尾匹配**: ```python Model.objects.filter(name__endswith='suffix') # 大小写敏感 Model.objects.filter(name__iendswith='suffix') # 大小写不敏感 ``` #### 3. 外键关联模糊查询 ```python # 查询 B 表中外键 aa 对应表的 name 字段含 "title" B.objects.filter(aa__name__icontains='title') ``` → 跨表查询语法:`关联字段__关联表字段__表达式` [^1] #### 4. 链式查询与排除 ```python # 多条件模糊查询 + 排序 results = Model.objects.filter( name__icontains='search', price__gt=100 ).exclude(status='deleted').order_by('-created_at') ``` #### 5. 完整示例(视图函数) ```python def search_view(request): if request.method == 'POST': keyword = request.POST.get('keyword', '') # 多字段模糊查询(书名或作者) results = Book.objects.filter( Q(title__icontains=keyword) | Q(author__name__icontains=keyword) ) return render(request, 'results.html', {'books': results}) ``` #### 📌 注意事项: 1. `icontains` 比 `contains` **性能更低**(大小写不敏感查询需扫描更多数据) 2. 避免在百万级数据表直接使用模糊查询,需配合索引优化 3. 可用 `Q对象` 实现复杂逻辑(OR/NOT查询
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值