Python Web开发技巧VIII

目录

ModelSerializer和Serializer区别是什么

从queryset中取出某个models的字段值

Q对象进行模糊匹配

HTTP方式-如何模糊搜索JSON字段中的某个KEY值呢?

showmigrations

合并两个或多个queryset


ModelSerializer和Serializer区别是什么

都是DRF中用于序列化和反序列化数据的组件。主要区别在于:ModelSerializer是针对Django模型(models)的快捷方式,它自动根据模型生成相应的序列化器字段和验证器。而Serializer则是一个通用的序列化器,需要手动定义字段和验证器。

  1. ModelSerializer
    • 针对Django模型的快捷方式。
    • 自动生成序列化器字段,根据模型中的字段类型选择相应的序列化器字段类型。
    • 自动生成验证器,根据模型中的字段约束(如unique, max_length等)创建相应的验证器。
    • 自动生成create()update()方法,用于创建和更新模型实例。
    • 需要定义一个Meta类,指定模型类和序列化器字段。
  2. Serializer
    • 通用的序列化器,适用于任何类型的数据。
    • 需要手动定义序列化器字段和验证器。
    • 需要手动实现create()update()方法(如果需要的话)。
    • 不需要定义Meta类。

大多数情况下,如果处理的数据与Django模型相关 ,那么ModelSerializer会更方便,它可以自动处理很多事情,减少了手动编写代码的工作。如果处理的数据与Django模型无关,或需要自定义序列化和验证逻辑,那么使用通用的Serializer可能更合适。

【注:serializers.Serializer 类不会自动使用 Meta 类。】

从queryset中取出某个models的字段值

python 复制代码
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表示返回一个单个值的列表 ,而不是元组

python 复制代码
# 使用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对象进行模糊匹配

icontainsiexactstartswith

python 复制代码
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执行,一般为优化代码,还同时把函数嵌套在函数里,例如一下这种写法:

python 复制代码
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对象对其进行模糊搜索,把对应匹配的字段数据返回。

核心代码:

python 复制代码
# 注:JSONField不支持__icontains查询,根据场景这里的user字段是JSONField
users = User.objects.filter(Q(user__contains={'name': name}))

showmigrations

python manager.py showmigrations会根据迁移的记录展示是否迁移(与django_migrations表相关联)

合并两个或多个queryset

用union

python 复制代码
queryset = queryset1.union(queryset2)

另外exists()属性可直接判断一个Queryset是否为空

相关推荐
张太行_1 小时前
C++中的析构器(Destructor)(也称为析构函数)
开发语言·c++
aiweker2 小时前
Selenium 使用指南:从入门到精通
python·selenium·测试工具
SteveKenny3 小时前
Python 梯度下降法(六):Nadam Optimize
开发语言·python
Hello.Reader4 小时前
深入浅出 Rust 的强大 match 表达式
开发语言·后端·rust
dreadp5 小时前
解锁豆瓣高清海报(二) 使用 OpenCV 拼接和压缩
图像处理·python·opencv·计算机视觉·数据分析
Tester_孙大壮5 小时前
第32章 测试驱动开发(TDD)的原理、实践、关联与争议(Python 版)
驱动开发·python·tdd
xrgs_shz6 小时前
MATLAB的数据类型和各类数据类型转化示例
开发语言·数据结构·matlab
小王子10248 小时前
设计模式Python版 组合模式
python·设计模式·组合模式
来恩10039 小时前
C# 类与对象详解
开发语言·c#