Python Web开发技巧VIII

目录

ModelSerializer和Serializer区别是什么

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

Q对象进行模糊匹配

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

showmigrations

合并两个或多个queryset


ModelSerializer和Serializer区别是什么

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

  1. ModelSerializer
    • 针对Django模型的快捷方式。
    • 自动生成序列化器字段,根据模型中的字段类型选择相应的序列化器字段类型。
    • 自动生成验证器,根据模型中的字段约束(如uniquemax_length等)创建相应的验证器。
    • 自动生成create()update()方法,用于创建和更新模型实例。
    • 需要定义一个Meta类,指定模型类和序列化器字段。
  2. 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对象进行模糊匹配

如 icontainsiexactstartswith 等

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

猜你喜欢

转载自blog.csdn.net/lxd_max/article/details/131955041