Elasticsearch不返回任何值。 Django

时间:2018-08-04 17:48:26

标签: python django elasticsearch

我正在尝试使用ElasticSearch为我的博客项目添加搜索引擎。我认为我所做的一切都正确(using this tutorial),但是无论我在搜索引擎中写什么,她始终不会返回任何结果。我的数据库有记录,一切看起来都很好。会发生什么?为什么不能返回任何结果?

任何帮助将不胜感激

我的urls.py

from django.conf.urls import url
from . import views
app_name = 'reviews'

urlpatterns = [
    # ex: /
    url(r'^$', views.review_list, name='review_list'),
    # ex: /review/5/
    url(r'^review/(?P<review_id>[0-9]+)/$', views.review_detail, name='review_detail'),
    # ex: /wine/
    url(r'^wine$', views.wine_list, name='wine_list'),
    # ex: /wine/5/
    url(r'^wine/(?P<wine_id>[0-9]+)/$', views.wine_detail, name='wine_detail'),
    url(r'^wine/(?P<wine_id>[0-9]+)/add_review/$', views.add_review, name='add_review'),
    url(r'^review/user/(?P<username>\w+)/$', views.user_review_list, name='user_review_list'),
    url(r'^review/user/$', views.user_review_list, name='user_review_list'),
    url(r'^review/search/$', views.search, name='search'),

]

我的views.py

rom django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect
from django.urls import reverse
from .models import Review, Wine
from .forms import ReviewForm
import datetime
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from .documents import ReviewDocument



def review_list(request):
    latest_review_list = Review.objects.order_by('-pub_date')[:9]
    context = {'latest_review_list':latest_review_list}
    return render(request, 'reviews/review_list.html', context)


def review_detail(request, review_id):
    review = get_object_or_404(Review, pk=review_id)
    return render(request, 'reviews/review_detail.html', {'review': review})


def wine_list(request):
    wine_list = Wine.objects.order_by('-name')
    context = {'wine_list':wine_list}
    return render(request, 'reviews/wine_list.html', context)


def wine_detail(request, wine_id):
    wine = get_object_or_404(Wine, pk=wine_id)
    form = ReviewForm()
    return render(request, 'reviews/wine_detail.html', {'wine': wine, 'form': form})

@login_required
def add_review(request, wine_id):
    wine = get_object_or_404(Wine, pk=wine_id)
    form = ReviewForm(request.POST)
    if form.is_valid():
        rating = form.cleaned_data['rating']
        comment = form.cleaned_data['comment']
        user_name = request.user.username
        review = Review()
        review.wine = wine
        review.user_name = user_name
        review.rating = rating
        review.comment = comment
        review.pub_date = datetime.datetime.now()
        review.save()
        # Always return an HttpResponseRedirect after successfully dealing
        # with POST data. This prevents data from being posted twice if a
        # user hits the Back button.
        return HttpResponseRedirect(reverse('reviews:wine_detail', args=(wine.id,)))

    return render(request, 'reviews/wine_detail.html', {'wine': wine, 'form': form})

def user_review_list(request, username=None):
    if not username:
        username = request.user.username
    latest_review_list = Review.objects.filter(user_name=username).order_by('-pub_date')
    context = {'latest_review_list':latest_review_list, 'username':username}
    return render(request, 'reviews/user_review_list.html', context)


def search(request):
    q = request.GET.get('q')
    if q:
        reviews = ReviewDocument.search().query("match", title=q)
    else:
        reviews = ''
    return render(request, 'reviews/search.html', {'Review': Review})

我的文档。py

from django_elasticsearch_dsl import DocType, Index
from .models import Review

reviews = Index('reviews')


@reviews.doc_type
class ReviewDocument(DocType):
    class Meta:
        model = Review

        fields = [
            'comment',
            'pub_date',
            'user_name',
            'rating',
        ]

我的模型。py

from django.db import models
import numpy as np


class Wine(models.Model):
    name = models.CharField(max_length=200)

    def average_rating(self):
        all_ratings = [list(map(lambda x: x.rating, self.review_set.all()))]
        return np.mean(all_ratings)

    def __unicode__(self):
        return self.name


class Review(models.Model):
    RATING_CHOICES = (
        (1, '1'),
        (2, '2'),
        (3, '3'),
        (4, '4'),
        (5, '5'),
    )
    wine = models.ForeignKey(Wine, on_delete=models.CASCADE)
    pub_date = models.DateTimeField('date published')
    user_name = models.CharField(max_length=100)
    comment = models.CharField(max_length=200)
    rating = models.IntegerField(choices=RATING_CHOICES)

settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'bootstrap3',
    'reviews',
    'registration',
    'django_elasticsearch_dsl',
]

ELASTICSEARCH_DSL = {
    'default': {
        'hosts': 'localhost:9200'
    },
}

search.html

<form method="get">

  <input id="q" name="q" type="text" placeholder="your search...">

</form>

{% for item in reviews %}

  {{ item.comment }}
  {{ item.pub_date }}
  {{ item.user_name }}
  {{ item.rating }}

  <br>

{% endfor %}

1 个答案:

答案 0 :(得分:1)

在不运行应用程序的情况下很难精确地确定发生问题的地方。但是,这里有一些指针可以帮助您查明问题的根源。 将您的Django应用程序想象成几层(紧跟MVC pattern之后):

  • 前端(视图层):您的浏览器解析并显示search.html,上面有一个表格。该视图是最终用户看到并与之交互的视图。

  • 路由(控制器层):urls.py,具有从URL到右控制器功能的映射(在views.py中)。控制器层负责获取正确的数据以返回给用户。

  • 持久性(模型层):models.pydocument.py定义了抽象和逻辑,以交互(读取和写入)您的ElasticSearch实例中存储的数据。

您在这里问“我在前端执行操作,但没有得到预期的结果,问题出在哪里?”。问题可能出在上述三层中的任何一层;您应该首先尝试将问题缩小到这些层之一。

您应该尝试回答以下问题:

  • 您的表单数据是否存储在服务器上? (即,视图<>控制器交互是否按预期方式工作)为此,您应该使用浏览器的开发人员工具来查看是否存在任何错误
  • 控制器是否对模型提出了正确的要求?为此,您应该在print
  • 中的正确函数中放置views.py条语句或断点(请参阅this question)。
  • 模型层是否以正确的方式查询ElasticSearch?这很难调试,因为Django隐藏了您的详细信息。