Reputation: 378
I am adding a search field in my blog so people can put the name of the blog they want to read and a list of items come up and after clicking on any of the list items, it will redirect to the detail view. However, in my case,If I put anything in search, it is not redirecting to a detail view but going to http://127.0.0.1:8000/home/search/2 instead of http://127.0.0.1:8000/home/list/2/.
I have posted my models, views, URLs and template files below.
Is there any reverse method I need to use here to redirect and what changes I need in my template file?
models.py
from django.db import models
class Category(models.Model):
cat_name = models.CharField(max_length = 256, blank = True)
def __str__(self):
return self.cat_name
class Blog(models.Model):
name = models.CharField(max_length = 256, blank = True)
pub_date = models.DateTimeField('date published')
text = models.TextField(blank = True)
category = models.ForeignKey(Category, on_delete=models.CASCADE,
related_name='categories', verbose_name = 'blog_categories')
def __str__(self):
return self.name
views.py
from django.shortcuts import render
from homepage.models import Blog
from django.views.generic import TemplateView, ListView, DetailView
from homepage import models
from django.db.models import Q
class Home(TemplateView):
template_name = 'homepage/index.html'
class BlogListView(ListView):
context_object_name = 'blogs'
model = models.Blog
template_name = 'homepage/blog_list.html'
class BlogDetailView(DetailView):
context_object_name = 'blogs_detail'
model = models.Blog
template_name = 'homepage/blog_detail.html'
def get_queryset(self):
query = self.request.GET.get('q')
return Blog.objects.filter(
Q(name__icontains = query) | Q(name__icontains = query) )
class SearchResultsListView(ListView):
model = Blog
context_object_name = 'blog_list'
template_name = 'homepage/search_result_list.html'
def get_queryset(self):
query = self.request.GET.get('q')
return Blog.objects.filter(
Q(name__icontains = query) | Q(name__icontains = query) )
urls.py
from django.urls import path
from homepage import views
from homepage.views import SearchResultsListView
app_name = 'homepage'
urlpatterns = [
path('', views.Home.as_view(), name = 'index'),
path('list/', views.BlogListView.as_view(), name = 'blog-list'),
path('list/<int:pk>/', views.BlogDetailView.as_view(), name = 'blog-list'),
path('search/', SearchResultsListView.as_view(), name = 'search_result'),
]
index.html
<div class="grid-item-1">
<h1>G</h1>
<input type="button" name="" value="Back to Home" placeholder="">
<a href="{% url 'home:index' %}"></a>
<form action="{% url 'home:search_result' %}" method = 'get'>
<input type="text" name="q" placeholder="search">
</form>
</div>
search_result_list.html
{% for blog in blog_list %}
<ul>
<li>
<a href="{{blog.id}}">{{blog.name}}</a>
{{blog.address}}
<a href="{{blog.id}}">here</a>
</li>
</ul>
{% endfor %}
the URL redirects to http://127.0.0.1:8000/home/search/2 and its a 404 page.
how can I redirect it to the detail view page http://127.0.0.1:8000/home/list/1/ and see the detail of the list pulled by search result.
Upvotes: 1
Views: 574
Reputation: 477210
The reason this happens is because {{ blog.id }}
just contains a number, for example 2
. It will be appended to the URL. You can fix this by prepending the URL with a slash (/
) and write list with:
<a href="/list/{{blog.id}}">{{blog.name}}</a>
{{blog.address}}
<a href="/list/{{blog.id}}">here</a>
But it is likely better to make use of the {% url … %}
template tag [Django-doc]:
<a href="{% 'blog-list' blog.id %}">{{blog.name}}</a>
{{blog.address}}
<a href="{% 'blog-list' blog.id %}">here</a>
In your BlogDetailView
, there is no q
parameter, so you can remove the get_queryset
:
class BlogDetailView(DetailView):
context_object_name = 'blogs_detail'
model = models.Blog
template_name = 'homepage/blog_detail.html'
# no get_queryset
Furthermore perhaps you should consider renaming the DetailView
from blog-list
, to blog-detail
, or something similar.
Upvotes: 2