【问题标题】:Django - How to implement a search boxDjango - 如何实现搜索框
【发布时间】:2021-05-24 11:55:24
【问题描述】:

我正在努力实现搜索栏,我真的可以就如何完成它提出一些建议。我是一个新手,所以请多多包涵。我的困难更多在于对需要构建的内容的一般理解,而不是特定的代码行,不知何故,这让我更难找到答案。

总之,我有:

Django 模型:

  • 食谱
  • 标签(带配方的 M2M)
  • 类别(带配方的外键)

我已经编写了 Graphene 模式来通过标签、类别和众多食谱属性(例如:食谱名称)来查询数据库 (Postgres)。您可以通过单击例如过滤这些查询在前端显示的食谱。某个类别名称。

不过,我还想拥有一个搜索框,用户可以在其中输入他们在前端选择的关键字,并获取与该关键字匹配的所有食谱。

我不知道什么或如何构建这样的东西。对我的新手来说,这种搜索框似乎本质上是一个查询,我事先不知道过滤器是什么,即“新鲜”作为输入可能是标签、类别、食谱的一部分名称等...并且我希望返回所有匹配的结果 - 理想情况下,搜索不会花费过多的时间。

我应该如何构建这样的东西?我已经构建了搜索框(React/Tailwind),所以当用户键入关键字并点击搜索时,后端需要提供什么。

感谢您的帮助! :)

以下代码显示了我的模型 -> Recipe 模型非常大(并非包含所有代码),因此也非常感谢任何有关如何降低搜索速度的提示。

class Recipe(models.Model):
..
..
..
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=50)
    description = models.TextField(max_length=512, default='')

    tags = models.ManyToManyField('tag.Tag')
    category = models.ForeignKey(
        'tag.Category',
        related_name='recipe_category',
        on_delete=models.SET_NULL,
        null=True,
    )
..
..
..

class Tag(models.Model):

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name


class Category(models.Model):

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name

编辑:添加代码

【问题讨论】:

  • 你能把你的模型代码贴在这里
  • 感谢 - 添加了相关型号代码
  • 您可能会发现 Django Haystack 非常适合此操作

标签: django graphene-django search-box


【解决方案1】:

因此,根据搜索词,您尝试查询类别表、标签表和食谱表。这里的icontains是一个Django相关的ORM实用程序,相当于SQL中的ILIKE。

from django.db.models import Q

# in your mutation
search_term = "from your graphene mutation"
categories = Category.objects.filter(name__icontains=search_term).values_list(
    "id", flat=True
)
tags = Tag.objects.filter(name__icontains=search_term).values_list("id", flat=True)
# here the Q object is used to build multiple or conditions
# the final query as response to your frontend
recipies = Recipe.objects.filter(Q(name__icontains=search_term) | Q(description__icontains=search_term) | Q(tags__in=tags) | Q(category__in=categories))

注意这里的查询数量,因为我们要查询多个表,响应可能会很慢,具体取决于数据库中数据的大小。通过对数据库进行适当的索引,您可以轻松克服这个问题,或者您甚至可以使用弹性搜索等全文搜索引擎等。

【讨论】:

  • 谢谢!这看起来是一个很好的方法。 - 也感谢有关搜索速度的信息 - 我也会将该要求添加到我的原始帖子中
  • 嗯,它已经足够快了。但如果您的数据很大并且包含大量文本字段,我不会推荐它。如果您的数据量很大。您可以使用 elasticsearch 并索引您的数据,或者您可以在 redis 或 memcache 中缓存一些频繁的查询。
  • 谢谢!然后这就是我要尝试的 - 该项目的数据集不是那么大,所以我假设这会很好,否则我将把注意力转移到学习如何实现索引/弹性搜索上。祝你有美好的一天!
猜你喜欢
  • 2012-12-13
  • 2014-08-15
  • 2019-11-20
  • 2021-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多