Reputation: 51
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>
Upvotes: 3
Views: 831
Reputation: 51
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)
Upvotes: 2