How do I get Django CMS to accept my page slug?

So I’m trying to build a Django CMS (3.7.4) site to replace an existing Django site. One of the pages on the original has a URL with CamelCase, but the “Change Page” admin form forces the slug to lowercase when I save.

I think I’ve traced it down to cms/admin/forms.py line 138, where BasePageForm.clean_slug does slug = slugify(self.cleaned_data['slug']). Does anyone have a recommendation for the best way to disable this “feature”?

I expect that, when manually changing a slug field, that the system not refill it with a generated value. (And, frankly, it seems silly to slugify a slug; you slugify titles.)

P.S. If you really want to use slugify, replace clean_slug with something like:

def clean(self):
    cleaned_data = super().clean()
    slug = cleaned_data.get('slug')
    if not slug:
        title = cleaned_data.get('title')
        self.cleaned_data['slug'] = slugify(title)

Hi @GreyHare I have seen others bypass this feature when rendering the url in the past via middleware but I can’t remember the exact use case of that so it’s possible that the middleware solution might not fit your use case.

With regards to why the slug field is slugified, this is done to ensure that what the user entered is in fact a valid slug, without this step the slug could be stored invalid.

1 Like

Yeah, but I’m in the admin, so I kind of expect changes to stick?

Maybe break “how to validate slug” out to a setting? Or add a “Validate” checkbox (checked by default) to the form?

Kind of at a loss as to how that specific a middleware could work. I’m not trying to rewrite slugs in-flight, I’m trying to get them not rewritten.

The slug is supposed to be formatted to be a valid slug, upper case character in urls is bad practice, it should be lowercase with the exception of parameters added via GET i.e. everything after “?”.

The slug field should be a valid slug, if it didn’t go through the conversion method then there would be validation to prevent a user adding invalid slug characters which would still block the entry of uppercase, basically it would need to follow the following rules: https://docs.djangoproject.com/en/3.1/ref/utils/#django.utils.text.slugify

My comment regarding the middleware is that you can see an incoming address that is camel cased and normalise it to lower.

Can you please provide more details regarding why the urls incoming are uppercased and provide a little more background to the need for using invalid slugs?

1 Like

I’m converting a site from a plain Django site to use CMS. I’m trying to match the original paths as much as possible, though the forced /en/ path prefix (instead of allowing the other methods for picking a language, such as request headers or cookies) is breaking that already. The original site didn’t have a requirement that all URL paths be slugs.

There’s no external requirement for URL path components to conform to Django’s django.utils.text.slugify algorithm. RFC3986 sections 2.3 and 3.3 allow uppercase, lowercase, digits, -, ., _, ~, /, :, and @ in paths.

Edit: Also !, $, &, ', (, ), *, +, ,, ;, and = (sub-delims) as well as %-encoded characters.