如果在 Jquery 自动完成和 Django 中不唯一,如何只显示一个结果
How to show only one result if it is not unique in a Jquery Autocomplete and Django
我刚刚在我的 Django 项目中使用 Jquery 添加了一个自动完成功能,通过向我展示结果,它似乎工作正常。唯一的问题是我想按目的地而不是标题搜索,因为我有多个 objects 具有相同的目的地值,并且我的自动完成设置为显示 5 个结果,所以我得到了 5 次相同的结果。如果它不是唯一的,如何设置它使自动完成只显示一个结果。
这里有一个link问题的图片:
我将此自定义 Javascript 代码用于自动完成:
$(function () {
'use strict';
$('#q').autocomplete({
serviceUrl: "http://127.0.0.1:8000/search/autocomplete/",
minChars: 2,
dataType: 'json',
type: 'GET',
onSelect: function (suggestion) {
console.log( suggestion.value + ', data :' + suggestion.data);
}
});
});
我的Views.py自动完成功能:
def autocomplete(request):
sqs = SearchQuerySet().autocomplete(
content_auto=request.GET.get(
'query',
''))[
:5]
s = []
for result in sqs:
d = {"value": result.destination, "data": result.object.slug}
s.append(d)
output = {'suggestions': s}
return JsonResponse(output)
我的Models.py:
class Product(models.Model):
destination = models.CharField(max_length=255, default='')
title = models.CharField(max_length=255, default='')
slug = models.SlugField(null=True, blank=True, unique=True, max_length=255, default='')
description = models.TextField(default='')
ptags = TaggableManager()
image = models.ImageField(default='')
timestamp = models.DateTimeField(auto_now=True)
def _ptags(self):
return [t.name for t in self.ptags.all()]
def get_absolute_url(self):
return reverse('product',
kwargs={'slug': self.slug})
def __str__(self):
return self.destination
在我的网址中:
from django.conf.urls import url
from django.contrib import admin
from search.views import HomeView, ProductView, FacetedSearchView, autocomplete
from .settings import MEDIA_ROOT, MEDIA_URL
from django.conf.urls.static import static
urlpatterns = [
url(r'^$', HomeView.as_view()),
url(r'^admin/', admin.site.urls),
url(r'^product/(?P<slug>[\w-]+)/$', ProductView.as_view(), name='product'),
url(r'^search/autocomplete/$', autocomplete),
url(r'^search/', FacetedSearchView.as_view(), name='haystack_search'),
] + static(MEDIA_URL, document_root=MEDIA_ROOT)
这是我的 search_indexes.py 文件:
import datetime
from django.utils import timezone
from haystack import indexes
from haystack.fields import CharField
from .models import Product
class ProductIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.EdgeNgramField(
document=True, use_template=True,
template_name='C:/Users/loicq/Desktop/Coding/UVERGO_SEARCH/venv/src/templates/search/indexes/product_text.txt')
title = indexes.CharField(model_attr='title')
description = indexes.EdgeNgramField(model_attr="description")
destination = indexes.EdgeNgramField(model_attr="destination")
image = indexes.CharField(model_attr="image")
# Tags
ptags = indexes.MultiValueField(model_attr='_ptags', faceted=True)
# for auto complete
content_auto = indexes.EdgeNgramField(model_attr='destination')
# Spelling suggestions
suggestions = indexes.FacetCharField()
def get_model(self):
return Product
def index_queryset(self, using=None):
"""Used when the entire index for model is updated."""
return self.get_model().objects.filter(timestamp__lte=timezone.now())
有什么解决办法吗?
这将在自动完成中包含产品标题:
for result in sqs:
d = {
"value": " - ".join((result.destination, result.title)),
"data": result.object.slug,
}
但如果您真的对产品不感兴趣,您可能不想要result.object.slug
中的data
。我猜你会去某个目的地的视图,所以目的地的一些标识符属于那里。为目的地建立一个单独的索引可能更好,但你可以像这样提取它们,使用集合理解和列表理解:
def autocomplete(request):
sqs = SearchQuerySet().autocomplete(
content_auto=request.GET.get('query',''))[:5]
destinations = {result.destination for result in sqs}
s = [{"value": dest, "data": dest} for dest in destinations]
output = {'suggestions': s}
return JsonResponse(output)
我假设您不需要保留订单(因为这是基于产品)。您可能希望预先获得超过 5 个结果,然后 trim 之后,以获得 5 个 distinct 个目的地的更多机会。
我刚刚在我的 Django 项目中使用 Jquery 添加了一个自动完成功能,通过向我展示结果,它似乎工作正常。唯一的问题是我想按目的地而不是标题搜索,因为我有多个 objects 具有相同的目的地值,并且我的自动完成设置为显示 5 个结果,所以我得到了 5 次相同的结果。如果它不是唯一的,如何设置它使自动完成只显示一个结果。
这里有一个link问题的图片:
我将此自定义 Javascript 代码用于自动完成:
$(function () {
'use strict';
$('#q').autocomplete({
serviceUrl: "http://127.0.0.1:8000/search/autocomplete/",
minChars: 2,
dataType: 'json',
type: 'GET',
onSelect: function (suggestion) {
console.log( suggestion.value + ', data :' + suggestion.data);
}
});
});
我的Views.py自动完成功能:
def autocomplete(request):
sqs = SearchQuerySet().autocomplete(
content_auto=request.GET.get(
'query',
''))[
:5]
s = []
for result in sqs:
d = {"value": result.destination, "data": result.object.slug}
s.append(d)
output = {'suggestions': s}
return JsonResponse(output)
我的Models.py:
class Product(models.Model):
destination = models.CharField(max_length=255, default='')
title = models.CharField(max_length=255, default='')
slug = models.SlugField(null=True, blank=True, unique=True, max_length=255, default='')
description = models.TextField(default='')
ptags = TaggableManager()
image = models.ImageField(default='')
timestamp = models.DateTimeField(auto_now=True)
def _ptags(self):
return [t.name for t in self.ptags.all()]
def get_absolute_url(self):
return reverse('product',
kwargs={'slug': self.slug})
def __str__(self):
return self.destination
在我的网址中:
from django.conf.urls import url
from django.contrib import admin
from search.views import HomeView, ProductView, FacetedSearchView, autocomplete
from .settings import MEDIA_ROOT, MEDIA_URL
from django.conf.urls.static import static
urlpatterns = [
url(r'^$', HomeView.as_view()),
url(r'^admin/', admin.site.urls),
url(r'^product/(?P<slug>[\w-]+)/$', ProductView.as_view(), name='product'),
url(r'^search/autocomplete/$', autocomplete),
url(r'^search/', FacetedSearchView.as_view(), name='haystack_search'),
] + static(MEDIA_URL, document_root=MEDIA_ROOT)
这是我的 search_indexes.py 文件:
import datetime
from django.utils import timezone
from haystack import indexes
from haystack.fields import CharField
from .models import Product
class ProductIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.EdgeNgramField(
document=True, use_template=True,
template_name='C:/Users/loicq/Desktop/Coding/UVERGO_SEARCH/venv/src/templates/search/indexes/product_text.txt')
title = indexes.CharField(model_attr='title')
description = indexes.EdgeNgramField(model_attr="description")
destination = indexes.EdgeNgramField(model_attr="destination")
image = indexes.CharField(model_attr="image")
# Tags
ptags = indexes.MultiValueField(model_attr='_ptags', faceted=True)
# for auto complete
content_auto = indexes.EdgeNgramField(model_attr='destination')
# Spelling suggestions
suggestions = indexes.FacetCharField()
def get_model(self):
return Product
def index_queryset(self, using=None):
"""Used when the entire index for model is updated."""
return self.get_model().objects.filter(timestamp__lte=timezone.now())
有什么解决办法吗?
这将在自动完成中包含产品标题:
for result in sqs:
d = {
"value": " - ".join((result.destination, result.title)),
"data": result.object.slug,
}
但如果您真的对产品不感兴趣,您可能不想要result.object.slug
中的data
。我猜你会去某个目的地的视图,所以目的地的一些标识符属于那里。为目的地建立一个单独的索引可能更好,但你可以像这样提取它们,使用集合理解和列表理解:
def autocomplete(request):
sqs = SearchQuerySet().autocomplete(
content_auto=request.GET.get('query',''))[:5]
destinations = {result.destination for result in sqs}
s = [{"value": dest, "data": dest} for dest in destinations]
output = {'suggestions': s}
return JsonResponse(output)
我假设您不需要保留订单(因为这是基于产品)。您可能希望预先获得超过 5 个结果,然后 trim 之后,以获得 5 个 distinct 个目的地的更多机会。