1

I'm having some issues with the slug field, the Error shows like this.

NoReverseMatch at /blog/ Reverse for 'blog_details' with keyword arguments '{'slug': 'We’ve-caught-a-black-hole-devouring-a-neutron-star-for-the-first-time-f84f375e-65a1-4b4a-b0e6-39a450e1d552'}' not found. 1 pattern(s) tried: ['blog/details/(?P[-a-zA-Z0-9_]+)$']

how to solve special character issues in the title...

this is the views:

        from django.shortcuts import render, HttpResponseRedirect
        from django.views.generic import CreateView, UpdateView, ListView, DetailView, DeleteView, TemplateView, View
        from app_blog.models import Blog, Comment, Likes
        from django.urls import reverse, reverse_lazy
        from django.contrib.auth.decorators import login_required
        from django.contrib.auth.mixins import LoginRequiredMixin
        import uuid
        
        
        # Create your views here.
        
        class CreateBlog (LoginRequiredMixin, CreateView) :
            model = Blog
            template_name = 'app_blog/create_blog.html'
            fields = ('blog_title', 'blog_content', 'blog_image',)
        
            def form_valid ( self, form ) :
                blog_obj = form.save (commit = False)
                blog_obj.author = self.request.user
                title = blog_obj.blog_title
                blog_obj.slug = title.replace (' ', '-') + '-' + str (uuid.uuid4 ())
                blog_obj.save ()
                return HttpResponseRedirect (reverse ('index'))
        
        
        class BlogList (ListView) :
            context_object_name = 'blogs'
            model = Blog
            template_name = 'app_blog/blog_list.html'
        
        
        @login_required
        def blog_details ( request, slug ) :
            blog = Blog.objects.get (slug = slug)
        
            return render (request, 'app_blog/blog_details.html', context = {'blog' : blog})
    
    
    

this is the model

    from django.db import models
    from django.contrib.auth.models import User
    
    
    # Create your models here.
    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 is used for using title in the url
        slug = models.SlugField (max_length = 264, unique = True)
        blog_content = models.TextField (verbose_name = 'Whats on your mind?')
        blog_image = models.ImageField (upload_to = 'blog_images', verbose_name = 'Image')
        publish_date = models.DateTimeField (auto_now_add = True)
        update_date = models.DateTimeField (auto_now = True)
    
        class Meta :
            ordering = ['-publish_date']
    
        def __str__ ( self ) :
            return self.blog_title
    
    
    class Comment (models.Model) :
        blog = models.ForeignKey (Blog, on_delete = models.CASCADE, related_name = 'blog_comment')
        user = models.ForeignKey (User, on_delete = models.CASCADE, related_name = 'user_comment')
        comment = models.TextField ()
        comment_date = models.DateTimeField (auto_now_add = True)
    
        class Meta :
            ordering = ('-comment_date',)
    
        def __str__ ( self ) :
            return self.comment
    
    
    class Likes (models.Model) :
        blog = models.ForeignKey (Blog, on_delete = models.CASCADE, related_name = 'liked_blog')
        user = models.ForeignKey (User, on_delete = models.CASCADE, related_name = 'liker_user')
    
        def __str__ ( self ) :
            return self.user + "likes" + self.blog

this is the HTML:

{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block title_block %} {{ blog.blog_title }} {% endblock %}
{% block body_block %}

    <div class = "row">
        <div class = "col-sm-6">
            <h2>{{ blog.blog_title }}</h2>
            <h4>Posted by: @{{ blog.author }}</h4>
            <i><h6>Publish on: {{ blog.publish_date }}</h6></i>
            <i><h6>Updated on: {{ blog.update_date }}</h6></i>
        </div>
        <div class = "col-sm-6">
            <img src = "/media/{{ blog.blog_image }}" width = "100%">
        </div>
        <p>{{ blog.blog_content|linebreaks }}</p>
    </div>

{% endblock %}
Al Amzad
  • 21
  • 2

1 Answers1

0

You should not slugify things yourself. Django has the slugify(…) function [Django-doc] for this:

from django.utils.text import slugify

# …

blog_obj.slug = f'{slugify(title)}-{uuid.uuid4()}
blog_obj.save()

This function normally guarantees that the outcome is a valid slug. It will:

  1. strip diacritics;
  2. convert it to lowercase;
  3. remove symbols; and
  4. join the groups with a hyphen (-).
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555