Reputation: 2177
I'm trying to add a search engine for my blog project using ElasticSearch. I think I did everything correctly (using this tutorial), but whatever I write in the search engine, she always returns no results. My database has records and everything looks good. What can happen? Why can not return any results?
Any help will be very appreciated
My 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'),
]
My 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})
My documents.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',
]
My models.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 %}
Upvotes: 0
Views: 244
Reputation: 978
It's hard to pinpoint exactly where things are breaking without running your application. However, here are some pointers that could help you pinpoint the source of the issue. Think of your Django application as several layers (following the MVC pattern):
Front-end (view layer): your browser parses and displays the search.html
, which has a form on it. The view is what the end user sees and interacts with.
Routing (controller layer): urls.py
with map from the URL to the right controller function (in views.py
). The controller layer is responsible for getting the right data to return to the user.
Persistence (model layer): models.py
and document.py
define abstractions and logic to interact (read from and write to) the data stored in your ElasticSearch instance.
Here you're asking "I do an action in the front-end and I don't get the expected result, where is the issue?". The issue could be in any of the above three layers; you should first try to narrow the issue down to one of those layers.
You should try to answer the following questions:
print
statements or breakpoints (see this question) in the the right function in views.py
Upvotes: 1