首页 > 解决方案 > 没有直接外部字段的其他模型上的 Django api 过滤器搜索

问题描述

我有两个模型,分别名为 user、skill 和 profile。我正在尝试对用户的技能实施搜索过滤器。这意味着当有人搜索用户技能中包含的内容时,该用户将出现在搜索结果中。

注意:当用户注册时,会使用一个信号为该用户自动创建个人资料。用户只需更新他们的个人资料以添加技能和其他内容。

用户模型

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(max_length=254, unique=True)
    name = models.CharField(max_length=250)
    picture = models.TextField(null=True, blank=True)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    last_login = models.DateTimeField(null=True, blank=True)
    date_joined = models.DateTimeField(auto_now_add=True)
    slug = models.SlugField(max_length=255, unique=True, blank=True)

轮廓模型

class Profile(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='profiles')
    date_of_birth = models.DateField(blank=True, verbose_name="DOB", null=True)
    bio = models.TextField(max_length=500, blank=True, null=True)
    skills = models.ManyToManyField(Skill, related_name='skills')
    sex = models.CharField(max_length=6, choices=SEX, blank=True, null=True)
    type_of_body = models.CharField(max_length=8, choices=BODYTYPE, blank=True, null=True)
    feet = models.PositiveIntegerField(blank=True, null=True)
    inches = models.PositiveIntegerField(blank=True, null=True)
    lives_in = models.CharField(max_length=50, blank=True, null=True)
    updated_on = models.DateTimeField(auto_now=True)

技能模型

class Skill(models.Model):
    name = models.CharField(max_length=60)
    subcategory = models.CharField(max_length=60, blank=True, null=True)
    description = models.TextField(null=True, blank=True)
    created_on = models.DateTimeField(auto_now=True)
    updated_on = models.DateTimeField(auto_now_add=True)
    updated_by = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.DO_NOTHING)

用户视图,从那里完成搜索

class ListUsersView(generics.ListAPIView):
    '''
    Gets all the users in the database
    '''
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [AllowAny]
    filter_backends = [filtr.SearchFilter]
    search_fields = ['email', 'name']

目前,上面的解决方案有效,但是当我添加到search_fields其他字段时,例如profiles__skills为了包含由任何用户创建的技能的结果,代码不起作用。

请问,我怎样才能获得用户个人资料中的技能以显示在搜索中?

标签: djangodjango-rest-frameworkdjango-filter

解决方案


SearchFilter 类支持简单的基于单个查询参数的搜索。search_fields 属性应该是模型上文本类型字段的名称列表。

profile__skills 不是一个字段。您应该使用文本字段,例如。个人资料__技能__名称

class ListUsersView(generics.ListAPIView):
    '''
    Gets all the users in the database
    '''
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [AllowAny]
    filter_backends = [filtr.SearchFilter]
    search_fields = ['email', 'name', 'profiles__skills__name']

推荐阅读