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对象进行模糊匹配

如 icontains,iexact,startswith 等

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是否为空

相关推荐
破茧蝴蝶9 小时前
Python分布式爬虫完整教程
开发语言·python
benchmark_cc9 小时前
量化系统架构设计:为什么应该将数据获取与策略逻辑解耦?
python·数据分析·pandas·量化交易·股票数据·quantdash
狗凯之家源码网9 小时前
全新 PHP 轻量客服聊天室源码深度评测
开发语言·php·聊天室系统
凤山老林10 小时前
Spring Boot 启动冲刺:耗时剖析、懒加载策略与事件驱动初始化优化
spring boot·后端·python
小白快快跑哦10 小时前
python-字符串全解(六):正则表达式-逻辑运算或
python·正则表达式·字符串·逻辑运算
远离UE410 小时前
UE5 Substrate Thin Film 源码拆析
开发语言·javascript·ue5
keyipatience10 小时前
JavaScript学习(1)书写位置,变量、数据类型、运算符
开发语言·前端·javascript·css·学习
Thinker QAQ10 小时前
并发编程(九):BlockingQueue 与 Channel——语言层的原子性、可见性与有序性
java·python·go·并发编程·channel·blockingqueue·message passing
道满科技10 小时前
Function Calling 参数总出错?只修参数就行
linux·windows·python
栈帧之外11 小时前
【C++】STL之set
开发语言·c++