makz
makz

Reputation: 97

django slug issue noreversematch

I'm new with django and I need little help to fix this issue. I'm getting error NoReverseMatch,

django.urls.exceptions.NoReverseMatch: Reverse for 'blog_details' with keyword arguments '{'slug': 'Cybercrime-Could-Cost-the-World-$10.5-Trillion-Annually-by-2025-aee2db6e-29ca-4ff9-94e8-09d8656905f3'}' not 
found. 1 pattern(s) tried: ['blog/details/(?P<slug>[-a-zA-Z0-9_]+)$']

I'm not sure where is my mistake and how can I fix this. Any help is appreciated! views.py

def blog_details(request, slug):
    blog = Blog.objects.get(slug=slug)
    return render(request, 'App_Blog/blog_details.html', context ={'blog':blog})

urls.py

urlpatterns = [
    path('', views.BlogList.as_view(), name = 'blog_list'),
    path('write/', views.CreateBlog.as_view(), name = 'create_blog'),
    path('details/<slug:slug>', views.blog_details, name = 'blog_details'),
]

blog_list.html

{% extends 'base.html' %}
{% block title %}  Detail{% endblock %}

{% block body_block %}
<h2>I am a blog list home page.</h2>
{% if blogs %}
    {% for blog in blogs %}
    <h2>{{ blog.blog_title }}</h2>
    <div class="row">
        <div class="col-sm-4">
            <img src = "{{ blog.blog_image.url }}" alt="{{ blog.blog_title }}" width='100%;'>
        </div>
        <div class="col-sm-8">
            <p>{{ blog.blog_content | linebreaks }} 
                <a href = "{% url 'blog_details' slug=blog.slug %}">Read More</a>
            </p>
        </div>
        <p><i>{{ blog.publish_date }}</i></p>
        <h5>Posted by {{ blog.author }}</h5>
    </div>
    {% endfor %}

{% else %}
    <p>No articles available!</p>
{% endif %}

{% endblock %}

models.py

class Blog(models.Model):
    author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='post_author')
    blog_title = models.CharField(max_length=264, verbose_name='Put a title') 
    slug = models.SlugField(max_length=264, unique = True)
    blog_content = models.TextField(verbose_name='What is on your mind?')
    blog_image = models.ImageField(upload_to = 'blog_images', verbose_name='Blog image')
    publish_date = models.DateTimeField(auto_now_add=True)
    update_date = models.DateTimeField(auto_now=True)

Upvotes: 1

Views: 50

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476740

This will not work since your "slug" contains an invalid character. Indeed:

Cybercrime-Could-Cost-the-World-$10.5-Trillion-Annually-by-2025-aee2db6e-29ca-4ff9-94e8-09d8656905f3

contains a $, a slug however can not contain a $. The <slug:… path converter uses as regex [GitHub]:

class SlugConverter(StringConverter):
    regex = '[-a-zA-Z0-9_]+'

So it can only contain hyphens (-), alphanumerical characters, and an underscore.

You should slugify the title properly. You can do this with the slugify(…) function [Django-doc], for example:

>>> from django.utils.text import slugify
>>> slugify('Cybercrime Could Cost the World $10.5 Trillion Annually by 2025')
'cybercrime-could-cost-the-world-105-trillion-annually-by-2025'

I would advise to use this function instead of implementing your own slug function, since it contains some extra logic to remove diacritics, such that ù is for example transformed to u:

>>> slugify('più')
'piu'

Upvotes: 1

Related Questions