3

I have simple Model with title and slug fields. I want to accept non-Latin characters as a title and transliterate them into Latin slug. Specifically, I want to transliterate Cyrillic characters, say 'Привет, мир!' into Latin 'privet-mir' slug. Instead of slug I'm getting following error:

NoReverseMatch at /blog/

Reverse for 'blog_detail' with arguments '('',)' not found. 1 pattern(s) tried: ['blog/(?P[-a-zA-Z0-9_]+)/$']

Django Version: 3.1.5
Python Version: 3.9.1
Exception Type: NoReverseMatch
Exception Value:    

Reverse for 'blog_detail' with arguments '('',)' not found. 1 pattern(s) tried: ['blog/(?P<slug>[-a-zA-Z0-9_]+)/$']

Model

from django.db import models 
from django.template.defaultfilters import slugify


class Post(models.Model):
    title = models.CharField(max_length=70)
    slug = models.SlugField(null=False, unique=True, allow_unicode=True)

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title)
        return super().save(*args, **kwargs)

    def __str__(self):
        return self.title

admin.py

from django.contrib import admin
from .models import Post


class PostAdmin(admin.ModelAdmin):
    prepopulated_fields = {'slug': ('title',)}

admin.site.register(Post, PostAdmin)

urls.py

from django.urls import path
from . import views

    app_name = 'blog'
    urlpatterns = [
        path('', views.BlogList.as_view(
            template_name=app_name + "/blog_list.html"), name='blog_list'),
        path('<slug:slug>/', views.BlogDetail.as_view(
            template_name=app_name + "/blog_detail.html"), name='blog_detail'),
    ]

views.py

from .models import Post
from django.views.generic import ListView, DetailView

class BlogList(ListView):
    model = Post

class BlogDetail(DetailView):
    model = Post

blog_list.html (for each post)

<a href="{% url 'blog:blog_detail' post.slug %}">{{ post.title }}</a>

blog_detail.html (short)

<h1>{{ post.title }}</h1>
Eugene S.
  • 51
  • 4
  • The slug value being passed to the URL resolvers is empty which is why you see `arguments '('',)'` in the error. This is showing that an empty string has been passed as the arguments. You'll need to debug this further to establish why there's no value being set in your save method. – markwalker_ Jan 30 '21 at 01:23
  • Thanks for the response. I understand why I'm getting an error. Question is how to fix it. .I see in admin panel that there is no slug in slug field. As I have 'null=False' Django gives me the error. Is it possible to see some sort of logs in Django? All I have is posted above and it is not very helpful for getting the right reason of the issue – Eugene S. Jan 30 '21 at 01:29

1 Answers1

2

I found the solution!

Thanks to KenWhitesell https://forum.djangoproject.com/t/django-slugify-error/6153/4 and Evgeny https://stackoverflow.com/a/4036665/15109119

It is also possible to use javascript, for example, as is used to auto populate the slug-field in the Django admin panel. It needs to use 'allow_unicode=True' while actually 'slugifying' the field.

def save(self, *args, **kwargs):
    if not self.slug:
        self.slug = slugify(self.title, allow_unicode=True)
    return super().save(*args, **kwargs)
Eugene S.
  • 51
  • 4