Searching result is not appearing in second page what should I change to solve my problem ? and I'm using elasticsearch as search engine
index.html
<ul>
{% for i in paginator.page_range %}
{% if i <= page_number|add:5 and i >= page_number|add:-5 %}
<li class=" {% if i == page_number %} active {% endif %} " >
{{forloop.counter}}
</li>
{% endif %}
{% endfor %}
</ul>
and this is in my views.py
def index(request):
q = request.GET.get('q')
if q:
articles = PostDocument.search().query("match", title=q, )
paginator = Paginator(articles, 5)
page_number = request.GET.get('page', 1)
page_obj = paginator.get_page(page_number)
return render(request, 'index.html', {
'articles': page_obj.object_list,
'paginator': paginator,
'page_number': int(page_number),
})
else:
articles = ''
return render(request, 'index.html', {'articles': articles})
If you write ?page=…, then the ?q=… parameter is "dropped". The trick is to add it to the querystring when you go to the next object:
def index(request):
q = request.GET.get('q')
if q:
articles = PostDocument.search().query("match", title=q, )
paginator = Paginator(articles, 5)
page_number = request.GET.get('page', 1)
page_obj = paginator.get_page(page_number)
return render(request, 'index.html', {
'articles': page_obj.object_list,
'paginator': paginator,
'page_number': int(page_number),
'q' : q
})
else:
articles = ''
return render(request, 'index.html', {'articles': articles})
and then render this with:
{{forloop.counter}}
The |urlencode template filter [Django-doc] is necessary to percentage encode the query, for example if it contains a question mark (?), ampersand (&), etc.
Related
First of all, hello everyone. I apologize to everyone for my bad English, I will try my best. I am making a video site, in this site there are three main views, they are single-video-view, index-view and main-view. All other views extends from main-view (%extends 'base/main.html' %). There is a sidebar that should appear on all pages. In this sidebar, the categories of pre-loaded videos should be listed.
My urls.py:
urlpatterns = [
path('',views.index,name="index"),
path('main/',views.main,name="main"),
path('video/<slug:slug>/',views.video,name="video"),
#path('test/',views.category,name="setcategory"),
path('apivideo/',views.apivideo,name="apivideo"),
]
If I visit main.html directly working fine
Single video view, categories not listing
Index view, categories not listing
View.py:
def index(request):
# q = request.GET.get('q')
# if request.GET.get('q') != None:
if 'q' in request.GET and request.GET['q']:
page = request.GET.get('page', 1)
q = request.GET['q']
videos = Video.objects.filter(
Q(video_title__icontains=q) | Q(video_tags__icontains=q))
paginator = Paginator(videos, 24)
videos = paginator.page(page)
return render(request, 'base/index.html', {'videos': videos, 'q': q})
else:
main(request)
videos = Video.objects.all().order_by("-id")
paginator = Paginator(videos, 24)
page_number = request.GET.get('page')
videos = paginator.get_page(page_number)
return render(request, 'base/index.html', {'videos': videos})
def main(request):
setcategory = []
category = Video.objects.values_list('video_tags', flat=True)
for i in range(0, len(category)):
for x in range(0, len(category[i])):
categorycount = Video.objects.filter(Q(video_title__icontains=str(
category[i][x]).lower()) | Q(video_tags__icontains=str(category[i][x]).lower())).count()
if (categorycount >= 10):
print("if: " + str(categorycount))
setcategory.append(str(category[i][x]).lower())
else:
print("else: " + str(categorycount))
break
setcategory = sorted([*set(setcategory)])
return render(request, 'base/main.html', {'setcategory': setcategory})
def video(request, slug):
eachvideo = Video.objects.get(video_slug=slug)
randomVideo = list(Video.objects.all())
randomVideo = random.sample(randomVideo, 20)
return render(request, 'base/video.html', {'eachvideo': eachvideo, 'randomVideo': randomVideo})
Main.html:
Some HTML..
<ul class="sidebar navbar-nav toggled">
{% if setcategory %}
{% for category in setcategory %}
<li class="nav-item active">
<a class="nav-link" href="{% url 'index' %}?q={{category}}">
<i class="fas fa-fw fa-home"></i>
<span>{{category|title}}</span>
</a>
</li>
{% endfor %}
{% endif %}
</ul>
Some HTML..
The code I wrote for this works fine, but it only works when I add a redirect to the main-view specifically in the url .py file and go to the main view page. What I want is for these categories to appear in the sidebar when the user browses the index or other pages.
I would like to hide the Next button in my blog if there is no next blog post available.
Is there some kind of built-in method to check has_next has_previous or do I need to create some logic in my view and extend the template with let's say {% if Foo %} show button {% endif %} ?
views.py
def render_post(request, id):
category_count = get_category_count()
most_recent = Post.objects.order_by('-timestamp')[:3]
post = get_object_or_404(Post, id=id)
next_post_id = int(id) + 1
previous_post_id = int(id) - 1
PostView.objects.get(post=post)
context = {
'post': post,
'id': id,
'next_post_id': next_post_id,
'previous_post_id': previous_post_id,
'most_recent': most_recent,
'category_count': category_count,
}
return render(request, 'post.html', context)
html
<div id="button-wrapper">
<button class="buttons" type="submit">Previous</button>
<button class="buttons" type="submit">Next</button>
</div>
You could do it by checking that the previous/next posts exist and returning the results in the context:
views.py
def render_post(request, id):
category_count = get_category_count()
most_recent = Post.objects.order_by('-timestamp')[:3]
post = get_object_or_404(Post, id=id)
next_post_id = int(id) + 1
previous_post_id = int(id) - 1
try:
previous_post_exists = Post.objects.filter(id=previous_post_id).exists()
except Post.DoesNotExist:
previous_post_exists = False
try:
next_post_exists = Post.objects.filter(id=next_post_id).exists()
except Post.DoesNotExist:
next_post_exists = False
context = {
'post': post,
'id': id,
'next_post_id': next_post_id,
'previous_post_id': previous_post_id,
'previous_post_exists': previous_post_exists,
'next_post_exists': next_post_exists,
'most_recent': most_recent,
'category_count': category_count,
}
return render(request, 'post.html', context)
You would then need to check those values in your template:
html
<div id="button-wrapper">
{% if previous_post_exists %}
<button class="buttons" type="submit">Previous</button>
{% endif %}
{% if next_post_exists %}
<button class="buttons" type="submit">Next</button>
{% endif %}
</div>
I am tried but i am not getting the desired output for lazy loading
views.py
def post_detail(request, pk):
post = get_object_or_404(Post, pk=pk)
content_type = ContentType.objects.get_for_model(Post)
obj_id = post.id
comments = Comment.objects.filter(
content_type=content_type, object_id=obj_id)
parent_id = request.POST.get("parent_id")
csubmit = False
if parent_id:
content_type = ContentType.objects.get_for_model(Comment)
Comment.objects.create(content_type=content_type,
object_id=parent_id,
parent_id=parent_id,
user=request.user,
text=request.POST.get("text"))
if request.method == 'POST':
form = CommentForm(data=request.POST)
if form.is_valid():
new_comment = form.save(commit=False)
new_comment.content_type = content_type
new_comment.user = request.user
new_comment.save()
csubmit = True
else:
form = CommentForm()
paginator = Paginator(comments, 10)
try:
comments = paginator.page(page)
except PageNotAnInteger:
comments = paginator.page(1)
except EmptyPage:
comments = paginator.page(paginator.num_pages)
return render(request, 'post_detail.html', {'post': post,
'comments': comments, 'csubmit': csubmit, 'form': form})
I want to apply lazy loading in the above view and want to apply on template.Above i added pagination and rendered in template
post_details.html
{%for comment in comments %}
<br>
{{comment.text}}<br/>
by {{comment.user}}<br>
<a href='#' class="rep_cmt" data-parentid="
{{comment.id}}">Reply</a><br>
{% for comment in comment.children.all %}
{{comment}}
{% endfor %}
{%endfor%}
{% if comments.has_next %}
<a class="infinite-more-link" href="?page={{ comments.next_page_number
}}">More</a>
{% endif %}
<div class="loading" style="display: none;">
Loading...
</div>
<script>
var infinite = new Waypoint.Infinite({
element: $('.rep_cmt')[0],
onBeforePageLoad: function () {
$('.loading').show();
},
onAfterPageLoad: function ($items) {
$('.loading').hide();
}
});
</script>
In above i added script to render data in lazy loading process but it is not rendering
for some reason im unable to display the comments of a category_request and i have now idea why, is smb. maybe able to have an eye on that, praticaly i should work but i dont see the mistake here.
as far as i see I'm using category_request_comment from the view to get a releated comment objects from a category_request... any idea?
Template Snippet:
{% for category_request_comment in category_request_comments %}
<div class="comment">
<p>{{ category_request_comment.content|readmore:15 }}</p>
{% if category_request_comment.content.published_date %}
<div class="date">
<a>Comment by: {{ category_request_comment.author }}</a><br>
<a>Commented at: {{ category_request_comment.published_date }}</a>
</div>
{% endif %}
{% if request.user == category_request_comment.author %}
<a class="commentoption" href="{% url 'comment_edit' pk=category_request_comment.pk %}">Edit</a><a> | </a>
<a class="commentoption" href="{% url 'comment_delete' pk=category_request_comment.pk %}">Delete</a>
{% endif %}
</div>
{% endfor %}
views.py
def category_request_detail(request, pk):
category_request = get_object_or_404(CategoryRequests, pk=pk)
list_category_request = CategoryRequests.objects.get_queryset().filter(id=pk).order_by('-pk')
paginator = Paginator(list_category_request, 20)
page = request.GET.get('page')
category_request_comment = paginator.get_page(page)
return render(request, 'myproject/category_request_detail.html', {'category_request': category_request, 'category_request_comment': category_request_comment})
views.py (only for Reference)
def category_request_comment_new(request, pk):
if request.method == "POST":
form = CategoryRequestsCommentForm(request.POST)
if form.is_valid():
category_request = get_object_or_404(CategoryRequests, pk=pk)
requests_comment = form.save(commit=False)
requests_comment.author = request.user
requests_comment.published_date = timezone.now()
requests_comment.category_request = category_request
requests_comment.save()
return redirect('category_request_detail', pk=requests_comment.category_request.pk)
else:
form = CategoryRequestsCommentForm()
return render(request, 'myproject/comment_new.html', {'form': form})
urls.py
url(r'^categories/requests/$', myproject_views.category_request_list, name='category_request_list'),
Thanks in advance
Your template is looking for an object called category_request_comments, but you have not sent anything with that name to the template.
def category_request_detail(request, pk):
category_request = get_object_or_404(CategoryRequests, pk=pk)
list_comments = CategoryRequests_Comment.objects.get_queryset().filter(category_request_id=pk).order_by('-pk')
paginator = Paginator(list_comments, 10)
page = request.GET.get('page')
comments = paginator.get_page(page)
return render(request, 'myproject/category_request_detail.html', {'category_request': category_request, 'comments': comments})
I have a view that filters out results for a posted search form:
def profile_advanced_search(request):
args = {}
if request.method == "POST":
form = AdvancedSearchForm(request.POST)
qs=[]
if form.is_valid():
cd = form.cleaned_data
s_country=cd['country']
s_province=cd['province']
s_city = cd['city']
if s_country: qs.append(Q(country__icontains = s_country))
if s_province: qs.append( Q(province__icontains=s_province))
if s_city: qs.append( Q(city__icontains=s_city))
f = None
for q in qs:
if f is None:
f=q
else: f &=q
list = UserProfile.objects.filter(f).order_by('-created_at')
else:
form = AdvancedSearchForm()
list = UserProfile.objects.all().order_by('-created_at')
paginator = Paginator(list,10)
page= request.GET.get('page')
try:
results = paginator.page(page)
except PageNotAnInteger:
results = paginator.page(1)
except EmptyPage:
results = paginator.page(paginator.num_pages)
args.update(csrf(request))
args['form'] = form
args['results'] = results
return render_to_response('userprofile/advanced_search.html', args,
context_instance=RequestContext(request))
the urls.py part is:
url(r'^search/$', 'userprofile.views.profile_advanced_search'),
The template is:
<form action="/search/" method="post">{% csrf_token %}
<ul class="list-unstyled">
<li><h3>Country</h3></li>
<li>{{form.country}}</li><br>
<h4>Province</h4>
<li>{{form.province}}</li>
<h4>City</h4>
<li>{{form.city}}</li>
</ul>
<input type="submit" name="submit" value="search" />
</form>
Search Results:
{% for p in results %}
<div">
<div>
<br>
<strong><a href="/profile/{{p.username}}" >{{p.username}}</a></strong>
{{p.country}} <br>
{{p.province}} <br>
{{p.city}} <br>
</div>
</div>
{% endfor %}
<div>
<div class="pagination">
{% if results.has_previous %}
<< Prev  
{% endif %}
{% if results.has_next %}
Next >>
{% endif %}
</div>
</div>
</div>
These work fine for the first page, but to deal with the later pages, it is suggested that I need to implement Post/Redirect/Get .
However I have had difficulty to make such views/template/urls to deal with GET pages regarding that all of the search parameters are arbitrary. So I appreciate a complete solution.
Do you need 2 views. First one for form search and second one to show results. You have not implemented redirect in any way in your sample code!
urls
...
url(r'^search/$',
'userprofile.views.profile_advanced_search'),
url(r'^show/(?P<country>\w+)/(?P<province>\w+)/(?P<site>\w+)/(?P<page>\d+)',
'userprofile.views.profile_advanced_show'),
...
profile_advanced_search
def profile_advanced_search(request):
args = {}
if request.method == "POST":
form = AdvancedSearchForm(request.POST)
qs=[]
if form.is_valid():
cd = form.cleaned_data
s_country=cd['country']
s_province=cd['province']
s_city = cd['city']
return HttpResponseRedirect(
reverse('userprofile.views.profile_advanced_show',
args=(s_country, s_province, s_city, 0, )))
return HttpResponseRedirect(
reverse('userprofile.views.profile_advanced_show',
args=('+', '+', '+', 0, )))
profile_advanced_show
def profile_advanced_show(request, s_country='',
s_province='', s_city='', page=0):
f = some filters with s_country, s_province and s_city
list = UserProfile.objects.filter(f).order_by('-created_at')
paginator = Paginator(list,10)
try:
results = paginator.page(page)
except PageNotAnInteger:
results = paginator.page(1)
except EmptyPage:
results = paginator.page(paginator.num_pages)
args.update(csrf(request))
form = AdvancedSearchForm(initial={ 's_country': s_country, ... } )
args['form'] = form
args['results'] = results
return render_to_response('userprofile/advanced_search.html', args,
context_instance=RequestContext(request))
Notice: improve it for not valid form submissions. Remember you can send parameters to second view via GET as key value instead route values.