我在我的django博客中使用Solr和Haystack实现了“搜索功能”。在“http://127.0.0.1:8000/blog/search/“中,它说/blog/search/ post_detail()中的TypeError缺少3个必需的位置参数:“year”、“month”和“day”同样在“http://localhost:8000/blog/search”中,它显示/blog/search处的ValueError视图blog.views.post_search未返回HttpResponse对象。它返回了None。
- 博客forms.py
from django import forms
class SearchForm(forms.Form):
query = forms.CharField()
- 博客/搜索索引.py
from haystack import indexes
from .models import Post
class PostIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
publish = indexes.DateTimeField(model_attr='publish')
def get_model(self):
return Post
def index_queryset(self, using=None):
return self.get_model().published.all()
- 博客urls.py
from blog.feeds import LatestPostsFeed
from django.conf.urls import url
from django.urls import include, path
from . import views
app_name = 'blog'
urlpatterns = [
path('search', views.post_search, name='post_search'),
]
- 博客views.py
from .forms import SearchForm
from haystack.query import SearchQuerySet
def post_search(request):
form = SearchForm()
if 'query' in request.GET:
form = SearchForm(request.GET)
if form.is_valid():
cd = form.cleaned_data
results = SearchQuerySet().models(Post).filter(content=cd['query']).load_all()
# count total results
total_results = results.count()
return render(request, 'blog/post/search.html', {'form': form, 'cd': cd, 'results': results, 'total_results': total_results})
- blog/templates/blog/post/search.html
{% extends "blog/base.html" %}
{% block title %}Search{% endblock %}
{% block content %}
{% if "query" in request.GET %}
<h1>Posts containing "{{ cd.query }}"</h1>
<h3>Found {{ total_results }} result{{ total_results|pluralize}}</h3>
{% for result in results %}
{% with post=result.object %}
<h4><a href="{{ post.get_absolute_url }}">{{ post.title }}</a></h4>
{{ post.body|truncatewords:5 }}
{% endwith %}
{% empty %}
<p>There are no results for your query.</p>
{% endfor %}
<p><a href="{% url 'blog:post_search' %}">Search again</a></p>
{% else %}
<h1>Search for posts</h1>
<form action="." method="get">
{{ form.as_p }}
<input type="submit" value="Search">
</form>
{% endif %}
{% endblock %}
- blog/templates/search/indexes/blog/post_text.txt
{{ object.title }}
{{ object.tags.all|join:", " }}
{{ object.body }}
编辑1
- 博客urls.py
from blog.feeds import LatestPostsFeed
from django.conf.urls import url
from django.urls import include, path
from . import views
app_name = 'blog'
urlpatterns = [
path('', views.post_list, name='post_list'),
url(r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/(?P<slug>[-\w]+)/$', views.post_detail, name='post_detail'),
url(r'^(?P<post_id>\d+)/share/$', views.post_share, name='post_share'),
path('<slug:slug>/', views.post_detail, name='post_detail'),
url(r'^tag/(?P<tag_slug>[-\w]+)/$', views.post_list, name='post_list_by_tag'),
path('feed', LatestPostsFeed(), name='post_feed'),
url(r'^search/$', views.post_search, name='post_search'),
]
```
- blog/views.py
```python
from django.shortcuts import render, get_object_or_404
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.core.mail import send_mail
from django.views.generic import ListView
from django.db.models import Count
from taggit.models import Tag
from .models import Post, Comment
from .forms import EmailPostForm, CommentForm, SearchForm
from haystack.query import SearchQuerySet
def post_list(request, tag_slug=None):
object_list = Post.published.all()
tag = None
if tag_slug:
tag = get_object_or_404(Tag, slug=tag_slug)
object_list = object_list.filter(tags__in=[tag])
paginator = Paginator(object_list, 3) # 3 posts in each page
page = request.GET.get('page')
try:
posts = paginator.page(page)
except PageNotAnInteger:
# If page is not an integer deliver the first page
posts = paginator.page(1)
except EmptyPage:
# If page is out of range deliver last page of results
posts = paginator.page(paginator.num_pages)
return render(request, 'blog/post/list.html', {'page': page, 'posts': posts, 'tag': tag})
def post_detail(request, year, month, day, slug):
post = get_object_or_404(Post, slug=slug, status='published', publish__year=year, publish__month=month, publish__day=day)
# List of active comments for this post
comments = post.comments.filter(active=True)
new_comment = None
# Comment posted
if request.method == 'POST':
# A comment was posted
comment_form = CommentForm(data=request.POST)
if comment_form.is_valid():
# Create Comment object but don't save to database yet
new_comment = comment_form.save(commit=False)
# Assign the current post to the comment
new_comment.post = post
# Save the comment to the database
new_comment.save()
else:
comment_form = CommentForm()
# List of similar posts
post_tags_ids = post.tags.values_list('id', flat=True)
similar_posts = Post.published.filter(tags__in=post_tags_ids).exclude(id=post.id)
similar_posts = similar_posts.annotate(same_tags=Count('tags')).order_by('-same_tags', '-publish')[:4]
return render(request, 'blog/post/detail.html', {'post': post, 'comments': comments, 'comment_form': comment_form, 'similar_posts': similar_posts})
def post_share(request, post_id):
# Retrieve post by id
post = get_object_or_404(Post, id=post_id, status='published')
sent = False
if request.method == 'POST':
# Form was submitted
form = EmailPostForm(request.POST)
if form.is_valid():
# Form fields passed validation
cd = form.cleaned_data
post_url = request.build_absolute_uri(post.get_absolute_url())
subject = '{} ({}) recommends you reading "{}"'.format(cd['name'], cd['email'], post.title)
message = 'Read "{}" at {}\n\n{}\'s comments: {}'.format(post.title, post_url, cd['name'], cd['comments'])
send_mail(subject, message, 'ecrire06@korea.ac.kr', [cd['to']])
sent = True
else:
form = EmailPostForm()
return render(request, 'blog/post/share.html', {'post': post, 'form': form, 'sent': sent})
def post_search(request):
form = SearchForm()
if 'query' in request.GET:
form = SearchForm(request.GET)
if form.is_valid():
cd = form.cleaned_data
results = SearchQuerySet().models(Post).filter(content=cd['query']).load_all()
# count total results
total_results = results.count()
return render(request, 'blog/post/search.html', {'form': form, 'cd': cd, 'results': results, 'total_results': total_results})
class PostListView(ListView):
queryset = Post.published.all()
context_object_name = 'posts'
paginate_by = 3
template_name = 'blog/post/list.html'
```
# Edit 2
- views.py
```python
from django.shortcuts import render, get_object_or_404
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.core.mail import send_mail
from django.views.generic import ListView
from django.db.models import Count
from taggit.models import Tag
from .models import Post, Comment
from .forms import EmailPostForm, CommentForm, SearchForm
from haystack.query import SearchQuerySet
def post_list(request, tag_slug=None):
object_list = Post.published.all()
tag = None
if tag_slug:
tag = get_object_or_404(Tag, slug=tag_slug)
object_list = object_list.filter(tags__in=[tag])
paginator = Paginator(object_list, 3) # 3 posts in each page
page = request.GET.get('page')
try:
posts = paginator.page(page)
except PageNotAnInteger:
# If page is not an integer deliver the first page
posts = paginator.page(1)
except EmptyPage:
# If page is out of range deliver last page of results
posts = paginator.page(paginator.num_pages)
return render(request, 'blog/post/list.html', {'page': page, 'posts': posts, 'tag': tag})
def post_detail(request, year, month, day, slug):
post = get_object_or_404(Post, slug=slug, status='published', publish__year=year, publish__month=month, publish__day=day)
# List of active comments for this post
comments = post.comments.filter(active=True)
new_comment = None
# Comment posted
if request.method == 'POST':
# A comment was posted
comment_form = CommentForm(data=request.POST)
if comment_form.is_valid():
# Create Comment object but don't save to database yet
new_comment = comment_form.save(commit=False)
# Assign the current post to the comment
new_comment.post = post
# Save the comment to the database
new_comment.save()
else:
comment_form = CommentForm()
# List of similar posts
post_tags_ids = post.tags.values_list('id', flat=True)
similar_posts = Post.published.filter(tags__in=post_tags_ids).exclude(id=post.id)
similar_posts = similar_posts.annotate(same_tags=Count('tags')).order_by('-same_tags', '-publish')[:4]
return render(request, 'blog/post/detail.html', {'post': post, 'comments': comments, 'comment_form': comment_form, 'similar_posts': similar_posts})
def post_share(request, post_id):
# Retrieve post by id
post = get_object_or_404(Post, id=post_id, status='published')
sent = False
if request.method == 'POST':
# Form was submitted
form = EmailPostForm(request.POST)
if form.is_valid():
# Form fields passed validation
cd = form.cleaned_data
post_url = request.build_absolute_uri(post.get_absolute_url())
subject = '{} ({}) recommends you reading "{}"'.format(cd['name'], cd['email'], post.title)
message = 'Read "{}" at {}\n\n{}\'s comments: {}'.format(post.title, post_url, cd['name'], cd['comments'])
send_mail(subject, message, 'ecrire06@korea.ac.kr', [cd['to']])
sent = True
else:
form = EmailPostForm()
return render(request, 'blog/post/share.html', {'post': post, 'form': form, 'sent': sent})
def post_search(request):
form = SearchForm()
if 'query' in request.GET:
form = SearchForm(request.GET)
if form.is_valid():
cd = form.cleaned_data
results = SearchQuerySet().models(Post).filter(content=cd['query']).load_all()
# count total results
total_results = results.count()
return render(request, 'blog/post/search.html', {'form': form, 'cd': cd, 'results': results, 'total_results': total_results})
return render(request, 'blog/post/search.html', {'form': form})
class PostListView(ListView):
queryset = Post.published.all()
context_object_name = 'posts'
paginate_by = 3
template_name = 'blog/post/list.html'
- urls.py
from blog.feeds import LatestPostsFeed
from django.conf.urls import url
from django.urls import include, path
from . import views
app_name = 'blog'
urlpatterns = [
path('', views.post_list, name='post_list'),
path('<int:year>/<int:month>/<int:day>/<slug:slug>/', views.post_detail, name='post_detail'),
path('<int:post_id>/share/', views.post_share, name='post_share'),
path('tag/<slug:tag_slug>/', views.post_list, name='post_list_by_tag'),
path('feed/', LatestPostsFeed(), name='post_feed'),
path('search/', views.post_search, name='post_search'),
]
2条答案
按热度按时间wtlkbnrh1#
尝试这样做:-
"我改变了什么“
您在
if
语句中传递return render
,因此Django
假定return render
是if starement
的一部分。编辑-1
你在
get
的参数中传递"year", "month" and "day"
,根据year
发布?我不知道你为什么要把它们作为参数传递。你试图在一个
post_detail
页面中显示一个特定的帖子,但是你没有传递你想打开的帖子,我的意思是你没有传递Post's id
,所以Django永远不会知道你想看哪个帖子。你可以这样做:-
urls.py
views.py
并尝试删除
parameters
“年”、“月”和“日”ckx4rj1h2#
我仔细查看我的代码,发现解决错误的关键是再次添加return。
通过添加“返回呈现(请求,”blog/post/search.html“,{”表单“:form})”。