首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在基于Django的GraphQL API中为postgres表创建全局搜索字段的最佳方法?

在基于Django的GraphQL API中为postgres表创建全局搜索字段的最佳方法?
EN

Stack Overflow用户
提问于 2021-05-25 14:09:54
回答 1查看 293关注 0票数 0

我正在使用一个具有Django-石墨烯GraphQL API和postgres的角度UI。

目前,我已经实现了一项功能,通过为每个表添加一个"searchField“,并通过该表中每个项的创建和更新来实现全局搜索字段。使用graphql过滤器,每次用户进行全局搜索时,我都会过滤查询的searchField。我对Django非常陌生,所以我不确定这是否是一种有效的方法,但这就是我所拥有的:

创造突变

代码语言:javascript
运行
复制
class CreateUser(graphene.Mutation):
    class Arguments:
        input = UserInput(required=True)

    ok = graphene.Boolean()
    user = graphene.Field(UserType)

    @staticmethod
    def mutate(root, info, input=None):
        ok = True
        searchField = input.username if input.username is not None else "" + \
            input.title if input.title is not None else "" + \
            input.bio if input.bio is not None else ""
        user_instance = User(user_id=input.user_id, title=input.title, bio=input.bio,
                             institution_id=input.institution_id, searchField=searchField)
        user_instance.save()
        return CreateUser(ok=ok, user=user_instance)

更新突变

代码语言:javascript
运行
复制
class UpdateUser(graphene.Mutation):
    class Arguments:
        id = graphene.Int(required=True)
        input = UserInput(required=True)

    ok = graphene.Boolean()
    user = graphene.Field(UserType)

    @staticmethod
    def mutate(root, info, id, input=None):
        ok = False
        user = User.objects.get(pk=id)
        user_instance = user
        if user_instance:
            ok = True
            user_instance.name = input.name if input.name is not None else user.name
            user_instance.avatar = input.avatar if input.avatar is not None else user.avatar
            user_instance.institution_id = input.institution_id if input.institution_id is not None else user.institution_id
            user_instance.title = input.title if input.title is not None else user.title
            user_instance.bio = input.bio if input.bio is not None else user.bio
            user_instance.searchField = user_instance.searchField + \
                user_instance.name if user_instance.name is not None else ""
            user_instance.searchField = user_instance.searchField + \
                user_instance.title if user_instance.title is not None else ""
            user_instance.searchField = user_instance.searchField + \
                user_instance.bio if user_instance.bio is not None else ""
            user_instance.save()
            return UpdateUser(ok=ok, user=user_instance)
        return UpdateUser(ok=ok, user=None)

不确定您是否知道,但我对Python和Django非常陌生。我在这里要做的是,每次创建或更新用户记录时,我都会在表中维护一个名为searchField的字段,该字段将包含表中所有字段的字符串,我希望全局搜索能够触及这些字段。我就这样手动写了每一行。不确定这是否符合最佳做法。

这是用户模型。

用户模型

代码语言:javascript
运行
复制
class User(AbstractUser):
    name = models.CharField(max_length=50)
    email = models.EmailField(blank=False, max_length=255, unique=True)
    avatar = models.CharField(max_length=250, blank=True, null=True)
    institution = models.ForeignKey(
        'Institution', on_delete=models.PROTECT, blank=True, null=True)
    title = models.CharField(max_length=150, blank=True, null=True)
    bio = models.CharField(max_length=300, blank=True, null=True)
    searchField = models.CharField(max_length=600, blank=True, null=True)
    USERNAME_FIELD = 'username'
    EMAIL_FIELD = 'email'

这里有几件事。

首先,我知道我在更新变异解析器方法中设置更新

  1. 方面做错了什么。这是因为我对Python的知识很差。所以,如果有人能找出我做错了什么,那就太好了。
  2. ,我完全是自己做的,我不知道这种方法在效率上是否是一个好策略,还是已经有了一个很好的基于graphql的django api的解决方案。如果有,请指给我看。--

谢谢。

EN

回答 1

Stack Overflow用户

发布于 2021-05-31 08:53:07

是的,如果你想更新你的searchField,你必须从头开始构建它。如果您使用旧数据并附加新数据,如果您搜索旧数据,它将返回记录,这是您希望避免的事情。

关于你的第二个问题,你可以使用django-filter

步骤:

安装django-filter

  1. 创建一个基filterset类并向其添加search字段。

类CustomFilterSet(filters.FilterSet):search =filters.CharFilter(方法=‘search_filter’) def search_filter(self,queryset,field_name,value):返回queryset

  1. 为从自定义filterset类继承的模型创建filterset类,并重写search_filter方法。为了在查询集上执行or操作,请使用Q对象。在你的情况下,就像:

UserFilterSet类(CustomFilterSet):def search_filter(self,queryset,field_name,value):返回queryset.filter( Q(username__icontains=value) \x- Q(title__icontains=vallue) - Q(bio__icontains=value) )

,它在指定字段中查找值,而不考虑小写/大写。

  1. 创建graphql类型并将相关filterset_class添加到元类:

类UserType(DjangoObjectType):类元:模型=用户filterset_class = UserFilterSet接口= (relay.Node,)

现在,只需传递一个字符串,就可以全局搜索指定的字段。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67689743

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档