I get a 404 error if slug begins with “id-”

[A 404 error with “id-” in slug on multilingual website with Indonesian language in Django 3.0]

More details on https://stackoverflow.com/questions/61618166/a-404-error-if-slug-begins-with-id-on-multilingual-website-with-indonesian-la

Is it a bug, or I’m doing something wrong?

Could someone suggest a solution?

I can only suggest that you setup a minimal sample project which reproduces your issue. This will surely help other people to debug your issue.

Thanks to stackoverflow I’ve found the reason for this.

When LocaleMiddleware sees the request coming in, it tries to parse the language from the request. See https://github.com/django/django/blob/92507bf3ea4dc467f68edf81a686548fac7ff0e9/django/utils/translation/trans_real.py#L46 for the regular expression used. The allowed format is: any sequence of word characters, and optionally a dash and more word characters, after that it expects either the end of the string, or a / . In this case, it matches id-button/ , and understands that id-button is the language prefix for that request, causing Django to activate the id language.

I think there is problem in design for this, if someone needs custom locale like ‘id-button’ it should be set separately in settings.py

I’m a bit newbie in python&django, is there an instruction how to do this?

Not that I know of, but just create a new Django project and add the minimal code to reproduce the issue.

If you use i18n_patterns, you should really reserve the first path element for the language. Delegating to Django to decide if that part is a language prefix or any other slug will always be fragile.

I think there’s an issue here, but I’m not exactly sure what…

Clean project, enable LocaleMiddleware:

from django.conf.urls.i18n import i18n_patterns
from django.urls import path
from django.http import HttpResponse

def hello(request):
    return HttpResponse("hello")

urlpatterns = i18n_patterns(
    path("", hello),

/en/ 200.
/en-gb/ 200
/en-us/ 404

Using the URLconf defined in ticket_31540.urls, Django tried these URL patterns, in this order:
The current path, en-us/, didn't match any of these.

So this is because en-us isn’t a configured language but when determining the language we fellback to en correctly I guess, but then we didn’t resolve the URL using the same, or redirect to the fallback language URL.

It seems like that’s something we should do, or… ?


1 Like

For my particular case when ‘/en-us/’ isn’t set in languages, but there is an item with slug ‘/en-us/’ fallback to default language should solve the issue. And it looks like a good general solution.