目录
ModelSerializer和Serializer区别是什么
从queryset中取出某个models的字段值
Q对象进行模糊匹配
HTTP方式-如何模糊搜索JSON字段中的某个KEY值呢?
showmigrations
合并两个或多个queryset
ModelSerializer和Serializer区别是什么
都是DRF中用于序列化和反序列化数据的组件。主要区别在于:ModelSerializer
是针对Django模型(models)的快捷方式,它自动根据模型生成相应的序列化器字段和验证器。而Serializer
则是一个通用的序列化器,需要手动定义字段和验证器。
- ModelSerializer:
- 针对Django模型的快捷方式。
- 自动生成序列化器字段,根据模型中的字段类型选择相应的序列化器字段类型。
- 自动生成验证器,根据模型中的字段约束(如
unique
,max_length
等)创建相应的验证器。 - 自动生成
create()
和update()
方法,用于创建和更新模型实例。 - 需要定义一个
Meta
类,指定模型类和序列化器字段。
- Serializer:
- 通用的序列化器,适用于任何类型的数据。
- 需要手动定义序列化器字段和验证器。
- 需要手动实现
create()
和update()
方法(如果需要的话)。 - 不需要定义
Meta
类。
大多数情况下,如果处理的数据与Django模型相关,那么ModelSerializer
会更方便,它可以自动处理很多事情,减少了手动编写代码的工作。如果处理的数据与Django模型无关,或需要自定义序列化和验证逻辑,那么使用通用的Serializer
可能更合适。
【注:serializers.Serializer
类不会自动使用 Meta
类。】
从queryset中取出某个models的字段值
from myapp.models import MyModel
# 获取MyModel的QuerySet
queryset = MyModel.objects.all()
# 从QuerySet中获取某个字段(例如'field1')的值
field_values = queryset.values_list('field1', flat=True)
# 保证单个元素获取
field_value = queryset.values_list('field1', flat=True).first
flat=True
表示返回一个单个值的列表,而不是元组。
# 使用flat=True
result = queryset.values_list('field_name', flat=True)
# 返回结果类似:[value1, value2, value3, ...]
# 不使用flat=True
result = queryset.values_list('field_name')
# 返回结果类似:[(value1,), (value2,), (value3,), ...]
而次数subject.values_list("follow_up_count", flat=True).first则直接为0。
Q对象进行模糊匹配
如 icontains
,iexact
,startswith
等
from django.db.models import Q
from myapp.models import MyModel
# 获取 name 包含 'John' 或 'Jane' 的对象(不区分大小写)
result = MyModel.objects.filter(Q(name__icontains='John') | Q(name__icontains='Jane'))
# 获取 name 以 'J' 开头的对象(不区分大小写)
result = MyModel.objects.filter(Q(name__istartswith='J'))
# 获取 name 等于 'John' 或 'Jane' 的对象(不区分大小写)
result = MyModel.objects.filter(Q(name__iexact='John') | Q(name__iexact='Jane'))
往往我们使用Q对象时,对应的搜索框可以使用不止一个字段的检索,这时如何提供查询效率和简便代码呢?
我们一般采取先创建Q对象,如何按OR的方式塞入,再往里面创建不同的Q对象添加,最后一次filter执行,一般为优化代码,还同时把函数嵌套在函数里,例如一下这种写法:
def create_q_object(field_name, search_terms):
q_object = Q()
q_object.connector = "OR"
for term in search_terms.split(","):
q_object.children.append((f"{field_name}__icontains", term))
return q_object
query_set = self.get_queryset().filter(enabled=True)
con = Q()
if "name" in validated_data:
con.add(create_q_object("name", validated_data["name"]), "AND")
if "age" in validated_data:
con.add(create_q_object("age", validated_data["age"]), "AND")
query_set = query_set.filter(con)
注:
icontains
:不区分大小写的子字符串搜索
contains
: 区分大小写的子字符串搜索
HTTP方式-如何模糊搜索JSON字段中的某个KEY值呢?
假设场景:
数据库中存储字段user值为{name: hh, age: 18},在搜索栏中使用name=h,name通过序列化
器,请问如何用Q对象对其进行模糊搜索,把对应匹配的字段数据返回。
核心代码:
# 注:JSONField不支持__icontains查询,根据场景这里的user字段是JSONField
users = User.objects.filter(Q(user__contains={'name': name}))
showmigrations
python manager.py showmigrations会根据迁移的记录展示是否迁移(与django_migrations表相关联)
合并两个或多个queryset
用union
queryset = queryset1.union(queryset2)
另外exists()属性可直接判断一个Queryset是否为空