Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to highlight searched queries in result page of Django template?

Tags:

python

css

django

I have the following search query in views.py:

class SearchView(View):
    def get(self, request, *args, **kwargs):
        queryset = BlogPost.objects.all()
        query = request.GET.get('q')
        if query:
            queryset = queryset.filter(
                Q(title__icontains=query) |
                Q(content__icontains=query)
            ).distinct()
        context = {
            'queryset': queryset,
            'query': query,
        }
        return render(request, 'blogs/search_result.html', context)

and if I search a word like Tesla the results shown in result template is as below:

enter image description here

Please help me, how do I highlight the searched query in yellow color in Django templates? Thank you for help!

edit: This is the template code with search box

<div class="card my-4">
    <div class="card-body">
        <div class="card-title">Search blog</div>
        <form action="{% url 'blog:search_blog' %}">
            {% csrf_token %}
            <input type="text" class="form-control" name="q" placeholder="What are you looking for?">
            <input type="submit" value="Search" class="btn btn-success btn-sm mt-3">
        </form>
    </div>
</div>

This is the template for result_search

{% block content %}
<div class="container bg-light w-100">
    <h2 class="display-6 border-bottom py-3">Results for "{{ query }}"</h2>
    {% for post in queryset %}
    <div class="my-1">
        <a class="link" href="{{ post.get_absolute_url }}">{{ post.title }}</a>
    </div>
    {% endfor %}
</div>
{% endblock %}

Thank you

Edit 2: Daniel Roseman, Sir this is the html below I highlighted it in yellow. enter image description here

like image 934
Mir Stephen Avatar asked May 14 '19 10:05

Mir Stephen


2 Answers

You could do this in a template filter. Something like:

@register.filter
def highlight_search(text, search):
    highlighted = text.replace(search, '<span class="highlight">{}</span>'.format(search)
    return mark_safe(highlighted)

Now in your template you can do:

{% load my_tags %} # wherever you put the template filter

{% for post in queryset %}
<div class="my-1">
    <a class="link" href="{{ post.get_absolute_url }}">{{ post.title|highlight_search:query }}</a>
</div>
{% endfor %}

You'd need to send the search_text back with the context that renders the result page.

like image 64
Daniel Roseman Avatar answered Oct 21 '22 07:10

Daniel Roseman


You can also use a function from django-haystack but you will need to configure the simple backend on your settings:

pipenv install django-haystack

Your settings.py

INSTALLED_APPS = (
   'haystack'
)

HAYSTACK_CONNECTIONS = {
    'default': {
        'ENGINE': 'haystack.backends.simple_backend.SimpleEngine',
    },
}

Create a new template filter:

@register.filter
def highlight_search(text, search):
    from haystack.utils.highlighting import Highlighter
    highlight = Highlighter(search, html_tag='strong', css_class='highlighted', max_length=400)

    return highlight.highlight(text)

Your template will look something like this:

{{ result.htmldata|highlight_search:myquery|safe  }}

The built-in safe will render the html_tag that you choose on your implementation.

More info: https://django-haystack.readthedocs.io/en/master/highlighting.html

like image 2
Fernando Mariano Avatar answered Oct 21 '22 07:10

Fernando Mariano