本文最后更新于 2025-08-20,文章内容可能已经过时。

0x01 前言

最近需要设计两个个功能一个是前端输入中文或者拼音,在后端查找对应的字段,另外一个是前端多选框多选,后端返回包含对应多选框参数的数据,翻了一下官方文档和谷歌,网上例子不是很多,边看边摸索用法,随记录下用法,方便有需要的人使用。

0x02 使用流程

django模型类

# models.py
class depart(models.Model):
    Name = models.CharField(max_length=64, unique=True, verbose_name="板块名称", help_text="板块名称")
    Managers = models.ManyToManyField(to="user", blank=True, verbose_name="关联员工", db_constraint=False, help_text="关联员工")

    class Meta:
        db_table = "depart"
        verbose_name = "板块表"
        verbose_name_plural = verbose_name

class user(models.Model):
    Id = models.CharField(primary_key=True,max_length=64, verbose_name="员工号" , help_text="员工号")
    Name = models.CharField(max_length=64, verbose_name="姓名" , help_text="姓名")
    Depart = models.ForeignKey(to=depart, to_field="id", on_delete=models.CASCADE, verbose_name="关联板块", help_text="关联板块")
    EMail = models.EmailField(max_length=64, verbose_name="邮箱", help_text="邮箱")
    Mobile = models.CharField(max_length=64, blank=True, null=True, verbose_name="手机号", help_text="手机号")

    class Meta:
        db_table = "user"
        verbose_name = "人员表"
        verbose_name_plural = verbose_name

此处我将序列化类,过滤器类以及视图类均写在了一个文件夹中,为了方便观看,我把对应功能代码拆分开来,方便理解,文末会放该文件完整代码

序列化类

# views/user.py
from .models import user, depart
from rest_framework import serializers
from dvadmin.utils.serializers import CustomModelSerializer
class userSerializer(CustomModelSerializer):
    """
    序列化器
    """
    Depart_Name = serializers.CharField(source='Depart.Name', read_only=True)
    class Meta:
        model = user
        fields = "__all__"

class userCreateUpdateSerializer(CustomModelSerializer):
    """
    创建/更新时的列化器
    """
    class Meta:
        model = user
        fields = "__all__"

自定义过滤器类

# views/user.py
from uuslug import slugify
import django_filters
class CharInFilter(django_filters.BaseInFilter, django_filters.CharFilter):
    """
    字符类型过滤器,多选框过滤
    """
    pass


class userFilter(django_filters.FilterSet):
    """
    过滤器
    """

    search = django_filters.CharFilter(field_name="EMail", method="search_filter")
    # 该字段查询需要用逗号分割开,例如Depart=板块1,板块2
    Depart = CharInFilter(field_name="Depart", lookup_expr='in')

    def search_filter(self, queryset, name, value):
        """
        @params queryset: 为user.objects.all()返回的合集, 即视图类中的的queryset
        @params name: 为field_name
        @params value: 为前端通过search字段传过来的值
        """
        lookup = '__'.join([name, 'icontains'])
    
        return queryset.filter(**{
            lookup: slugify(value).replace('-', '')
            })
    class Meta:
        model = user
        fields = "__all__"

视图类

# views/user.py
from dvadmin.utils.viewset import CustomModelViewSet
class userViewSet(CustomModelViewSet):
    """
    list:查询
    create:新增
    update:修改
    retrieve:单例
    destroy:删除
    """
    queryset = user.objects.all()
    serializer_class = userSerializer
    filter_class = userFilter
    create_serializer_class = userCreateUpdateSerializer
    update_serializer_class = userCreateUpdateSerializer

0x03 查询结果

(1) 查询姓名

http://127.0.0.1:8000/api/user/?search=%E7%89%88%E4%B8%BB
{
  "code": 2000,
  "msg": "success",
  "data": {
    "page": 1,
    "total": 3,
    "limit": 10,
    "data": [
      {
        "Id": "10001",
        "modifier_name": null,
        "Depart_Name": "板块1",
        "Name": "版主1",
        "EMail": "banzhu1@email.com",
        "Mobile": "11011111111",
        "Depart": 1
      },
      {
        "Id": "10002",
        "modifier_name": null,
        "Depart_Name": "板块2",
        "Name": "版主2",
        "EMail": "banzhu2@email.com",
        "Mobile": "11022222222",
        "Depart": 3
      },
    ]
  }
}

(2) 查询姓名的部分拼音

http://127.0.0.1:8000/api/vulmanager/user/?search=chuli
{
  "code": 2000,
  "msg": "success",
  "data": {
    "page": 1,
    "total": 2,
    "limit": 10,
    "data": [
      {
        "Id": "90001",
        "modifier_name": null,
        "Depart_Name": "板块1",
        "Name": "处理人1",
        "EMail": "chuliren1@email.com",
        "Mobile": "11111111111",
        "Depart": 3
      },
      {
        "Id": "90002",
        "modifier_name": null,
        "Depart_Name": "板块2",
        "Name": "处理人2",
        "EMail": "chuliren2@email.com",
        "Mobile": "12222222222",
        "Depart": 4
      }
    ]
  }
}

0x04 完整的类

# views/user.py
from vulmanager.models import user, depart
from rest_framework import serializers
from dvadmin.utils.serializers import CustomModelSerializer
from dvadmin.utils.viewset import CustomModelViewSet
import django_filters
from uuslug import slugify

class userSerializer(CustomModelSerializer):
    """
    序列化器
    """
    Depart_Name = serializers.CharField(source='Depart.Name', read_only=True)
    class Meta:
        model = user
        fields = "__all__"

class userCreateUpdateSerializer(CustomModelSerializer):
    """
    创建/更新时的列化器
    """
    class Meta:
        model = user
        fields = "__all__"


class CharInFilter(django_filters.BaseInFilter, django_filters.CharFilter):
    """
    字符类型过滤器,多选框过滤
    """
    pass


class userFilter(django_filters.FilterSet):
    """
    过滤器
    """
    search = django_filters.CharFilter(field_name="EMail", method="search_filter")
    Depart = CharInFilter(field_name="Depart", lookup_expr='in')

    def search_filter(self, queryset, name, value):
        """
        @params queryset: 为user.objects.all()返回的合集, 即视图类中的的queryset
        @params name: 为field_name
        @params value: 为前端通过search字段传过来的值
        """
        lookup = '__'.join([name, 'icontains'])
    
        return queryset.filter(**{
            lookup: slugify(value).replace('-', '')
            })
    class Meta:
        model = user
        fields = "__all__"

class userViewSet(CustomModelViewSet):
    """
    list:查询
    create:新增
    update:修改
    retrieve:单例
    destroy:删除
    """
    queryset = user.objects.all()
    serializer_class = userSerializer
    filter_class = userFilter
    create_serializer_class = userCreateUpdateSerializer
    update_serializer_class = userCreateUpdateSerializer

(要是对你有帮助的话,点个赞和关注吧~)