Django - 如何实现搜索框
Django - How to implement a search box
我正在为实现搜索栏而苦苦挣扎,我真的可以就如何实现提出一些建议。我是一个新手,所以请多多包涵。我的困难更多在于对需要构建什么的一般理解,而不是特定代码行,不知何故这让我更难找到答案。
总而言之,我有:
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
编辑:添加代码
因此,根据搜索词,您正在尝试查询类别 table、标签 table 和食谱 table。这里 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))
请注意此处的查询数量,因为我们正在查询多个 table,响应速度可能会很慢,具体取决于数据库中数据的大小。通过在数据库上建立适当的索引,您可以轻松克服这个问题,或者您甚至可以使用诸如弹性搜索等全文搜索引擎之类的东西
我正在为实现搜索栏而苦苦挣扎,我真的可以就如何实现提出一些建议。我是一个新手,所以请多多包涵。我的困难更多在于对需要构建什么的一般理解,而不是特定代码行,不知何故这让我更难找到答案。
总而言之,我有:
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
编辑:添加代码
因此,根据搜索词,您正在尝试查询类别 table、标签 table 和食谱 table。这里 icontains 是一个 Django 相关的 ORM 实用程序,相当于 SQL.
中的 ILIKEfrom 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))
请注意此处的查询数量,因为我们正在查询多个 table,响应速度可能会很慢,具体取决于数据库中数据的大小。通过在数据库上建立适当的索引,您可以轻松克服这个问题,或者您甚至可以使用诸如弹性搜索等全文搜索引擎之类的东西