deepdiver
deepdiver

Reputation: 15

I have an error msg trying to use a slug field that contains an unusual character

My DB (MariaDB) is set to utf8mb4, my model and my view are all defined to use unicode characters. The creation of the record is ok and a slug is correctly created with a value as for example corée. The problem raise right after the creation with a NoReverse match error msg. I had a look to the documentation but I don't understand what I'm doing wrong. Thanks for your support.

NoReverseMatch at /masterdat/countrycode/ Reverse for 'countrycode_update' with keyword arguments '{'slug': 'corée'}' not found. 1 pattern(s) tried: ['masterdat/countrycode/(?P[-a-zA-Z0-9_]+)/$'] Request Method: GET Request URL: http://127.0.0.1:8000/masterdat/countrycode/ Django Version: 3.2.5 Exception Type: NoReverseMatch Exception Value:
Reverse for 'countrycode_update' with keyword arguments '{'slug': 'corée'}' not found. 1 pattern(s) tried: ['masterdat/countrycode/(?P[-a-zA-Z0-9_]+)/$']

URL:    
from django.urls import path

from masterdat import views
from masterdat.views import CountrycodeListView
from masterdat.views import CountrycodeCreateView, CountrycodeUpdateView 

urlpatterns = [
    path('masterdathome/', views.masterdathome, name='masterdathome'),
    path('countrycode/', CountrycodeListView.as_view(), 
    name='countrycode_list'),
    path('countrycode/add/', CountrycodeCreateView.as_view(), 
    name='countrycode_add'),
    path('countrycode/<slug:slug>/', CountrycodeUpdateView.as_view(), 
    name='countrycode_update'),    
]

Model:
class Countrycode(models.Model):
    cou_code = models.CharField(
        "Country name", max_length=40, primary_key=True)
    cou_recblocked = models.BooleanField("Country record blocked")
    cou_creator = models.ForeignKey(
        User, on_delete=models.PROTECT, related_name='+', 
    verbose_name="Created by")
    cou_creationdate = models.DateTimeField("Creation date", 
    auto_now=True)
    cou_modifier = models.ForeignKey(
        User, on_delete=models.PROTECT, related_name='+', 
    verbose_name="Last modification by")
    cou_modified = models.DateTimeField(
        "Last modification date", auto_now=True)
    slug = models.SlugField(max_length=50, allow_unicode=True)

    class Meta:
        ordering = ["cou_code"] 

    def __str__(self):
        return self.cou_code

    def get_absolute_url(self):
        return reverse('countrycode_update', kwargs={'slug': self.slug})

View:
from masterdat.models import Countrycode
#-----------------------
# List view Management
#-----------------------
class CountrycodeListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
    permission_required = 'masterdat.view_countrycode'
    
    model = Countrycode
    paginate_by = 10

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        return context

# Search bar
    def get_queryset(self):
        result = super(CountrycodeListView, self).get_queryset()

        query = self.request.GET.get('q')
        if query:
            query_list = query.split()
            result = result.filter(
                reduce(operator.and_,
                    (Q(cou_code__icontains=q) for q in query_list))
            )

        return result
#-----------------------------------
# Create and Update Views Management
#-----------------------------------
from masterdat.forms import CountrycodeForm

# Create View -----------
class CountrycodeCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
    permission_required = 'masterdat.add_countrycode'

    model = Countrycode
    form_class = CountrycodeForm
    success_url = reverse_lazy('countrycode_list')

    def form_valid(self, form):
        form.instance.slug = slugify(form.instance.cou_code, allow_unicode=True)
        form.instance.cou_creator = self.request.user
        form.instance.cou_modifier = self.request.user
        form.save
        return super().form_valid(form)

# Update View -----------
class CountrycodeUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
    permission_required = 'masterdat.change_countrycode'

    model = Countrycode
    form_class = CountrycodeForm
    success_url = reverse_lazy('countrycode_list')

    def form_valid(self, form):
        form.instance.cou_modifier = self.request.user
        form.save
        return super().form_valid(form)

Upvotes: 0

Views: 328

Answers (1)

snakecharmerb
snakecharmerb

Reputation: 55589

The regular expression (?P[-a-zA-Z0-9_]+) will only match "cor" because "é" is not a member of the range "A-Z" or "a-z".

You could change it to (?P[-\w0-9_]+) to match non-ASCII characters.

Upvotes: 2

Related Questions