赞
踩
filter()
是 QuerySet 对象的一个方法,用于从数据库中过滤数据。它接受一个或多个关键字参数,每个参数都表示一个查询条件,它们之间是 AND 关系。
以下是 filter()
方法的基本用法示例:
- from myapp.models import MyModel
-
- # 查询所有 name 字段值为 'John' 的记录
- results = MyModel.objects.filter(name='John')
-
- # 查询所有 age 大于等于 25 的记录
- results = MyModel.objects.filter(age__gte=25)
-
- # 多个条件的 AND 关系
- results = MyModel.objects.filter(name='John', age__gte=25)
-
- # 使用 OR 条件,使用 Q 对象
- from django.db.models import Q
- results = MyModel.objects.filter(Q(name='John') | Q(age__gte=25))
(1) name='John'
表示查询 name
字段等于 'John' 的记录。
(2) age__gte=25
表示查询 age
字段大于等于 25 的记录。
(3)
多个条件之间是 AND 关系,即同时满足所有条件。
(4)
使用 Q
对象可以实现 OR 关系,其中 Q(name='John') | Q(age__gte=25)
表示查询 name
字段等于 'John' 或 age
字段大于等于 25 的记录。
exact
: 等于,例如 field__exact=value
iexact
: 不区分大小写的等于,例如 field__iexact=value
contains
: 包含,例如 field__contains=value
icontains
: 不区分大小写的包含,例如 field__icontains=value
范围查询过滤器:
gt
: 大于,例如 field__gt=value
lt
: 小于,例如 field__lt=value
gte
: 大于等于,例如 field__gte=value
lte
: 小于等于,例如 field__lte=value
空值查询过滤器:
isnull
: 是否为空,例如 field__isnull=True
IN 查询过滤器:
in
: 在某个列表中,例如 field__in=[value1, value2]
日期查询过滤器:
date
: 根据日期进行查询,例如 pub_date__date=some_date
, pub_date__contains="2024-01"时间查询过滤器:
time
: 根据时间进行查询,例如 pub_time__time=some_time
外键查询过滤器:
ForeignKeyField__fieldname
: 对于外键关系,可以使用 __
来查询相关字段,例如 author__name__icontains=value
组合查询过滤器:
&
(与)和 |
(或):可以使用 &
和 |
符号来组合多个查询条件,例如 Q(field1=value1) | Q(field2=value2)
为什么已经有了Django ORM中的filter函数,还有整出个Django-ninja过滤器呢?
因为一般来说,从客户端用户发来一个请求,往往会带有很多查询参数。通过查询参数,在数据库中查找对应的记录。这些查询参数往往也并不是固定的。
如果我们直接通过手写代码构造filter需要的过滤条件,代码会相当丑陋,变得很难维护。
django-nina过滤器FilterSchema的作用就是对用户查询条件到数据库查询条件这一个过程的封装。
Django ORM的filter
关心数据库的数据,而Django Ninja的过滤器关心用户与我们网站互动的方式。
- from ninja import FilterSchema, Field
- from typing import Optional
-
-
- class BookFilterSchema(FilterSchema):
- name: Optional[str] = None
- author: Optional[str] = None
- created_after: Optional[datetime] = None
- @api.get("/books")
- def list_books(request, filters: BookFilterSchema = Query(...)):
- books = Book.objects.all()
- books = filters.filter(books)
- return books
自定义的过滤器继承FilterSchema。
1. filter_title_list方法用于处理title_list参数
- class BookFilterSchema(FilterSchema):
- """ 过滤器用于从用户的请求参数,转化为查询的过滤条件。
- 1. 默认使用类pub_date, title等字段进行过滤
- 2. 如果不能满足条件,可以使用自定义的函数对某一个参数编写函数进行过滤,函数名称使用filter_开头
- 3. 如果还不能满足要求,可以使用custom_expression定义一个完整的过滤查询器。这时候其他内置的
- 查询条件都会被忽略掉。
- """
- pub_date: date = Field(None) # 默认值为None,不使用这个过滤器
- # title__in: List[str] = Field(None, alias="titles")
- title: str = Field(None)
- title_list: str = Field(None) # 传输参数
- search: Optional[str] = Field(None, q=['title__icontains',
- 'pub_date__date'])
-
- def custom_expression(self) -> Q:
- """ 该函数如果定义了,将会被用作这个过滤器的自定义条件。其他所有的都会被忽略。"""
- q = Q()
- if self.title_list:
- titles = self.title_list.split(",")
- q = q & Q(title__in=titles)
- if self.title:
- q = q & Q(title=self.title)
- if self.pub_date:
- q = q & Q(pub_date=self.pub_date)
- if self.search:
- # sq = Q(title__icontains=self.search) | Q(pub_date__contains = Value(self.search, output_field=CharField()))
- sq = Q(title__icontains=self.search) | Q(pub_date__contains=self.search)
- q = q | sq
- return q
-
- def filter_title_list(self, value: str) -> Q:
- """自定义的过滤器函数,对传入的title_list字段转换成查询语句。
- title_list会使用‘,’进行切割,生产过滤条件。"""
- if value:
- titles = value.split(",")
- return Q(title__in=titles)
- else:
- return Q()
-
- @demo_api.get("/filter")
- def events(request, filters: BookFilterSchema = Query(...)): #
- books = Book.objects.all()
- print(filters.custom_expression())
- books = filters.filter(books)
- return ResponseSchema(data=books)
post请求可以包含Path,Query, Body等多个输入。下面的示例给出了继承Schema规整化这些输入。如果需要将相应的输入应用成过滤器,需要继承FilterSchema,编写相应的过滤方法。
- import datetime
-
- from ninja import NinjaAPI, Schema, UploadedFile, Form, File, Query, FilterSchema, Router, Path, Body
-
-
- class DogSchema(Schema):
- # name: str
- dog_type: str
- age: int
-
-
- class PathDate(Schema):
- year: int
- month: int
- day: int
-
- def value(self):
- return datetime.date(self.year, self.month, self.day)
-
-
- @demo_api.post("/dog_mix_post/{year}/{month}/{day}")
- def dog_mix_post(request, path: Path[PathDate], dog_item: DogSchema = Query(...), dog_item_body: DogSchema = Body(...)):
- """ name是路径参数;item是请求参数。"""
- return {"path": path.value(),
- "query": dog_item.dict(),
- "body": dog_item_body}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。