简体   繁体   中英

Search field in Django is not redirecting to detail view

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.

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="">{{blog.name}}</a>
{{blog.address}}
<a href="">here</a>

But it is likely better to make use of the {% url … %} template tag [Django-doc] :

<a href="">{{blog.name}}</a>
{{blog.address}}
<a href="">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 

Furthermore perhaps you should consider renaming the DetailView from blog-list , to blog-detail , or something similar.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM