Dots in a SlugField
When migrating from Plone to Django, I had problems with editing
weblog entries with a dot in the url. Apparently Django doesn’t allow
dots in a SlugField
. Here’s how I solved it.
First a bit of background information. The previous version of this site was created with Plone and I had a number of weblog entries with a dot in the URL. I did not want to change those URLs but I also wanted to be able to edit the weblog entries.
The biggest problem I had, was getting the SlugField
being validated
if there was a dot in it. There’s an
old ticket (#5368) where
this is discussed, but it has been closed as “wontfix.” The
last comment
pointed me in the right direction:
Slug fields are for a particular style of string. Underneath, though, they are just character fields with a validator. So if you want different validation requirements, just use a CharField and your own validator.
However, instead of using a CharField
, I chose to create my own
SlugField
(MySlugField
). This subclasses the Django SlugField
but
has a modified validator. In other words, my admin.py
looks very
similar to this:
import re
from django.contrib import admin
from django.core.validators import RegexValidator
from django.forms.fields import SlugField
from django.forms.models import ModelForm
from blog.models import BlogEntry
slug_re = re.compile(r'^[-\w.]+$')
validate_slug = RegexValidator(slug_re,
u"Enter a valid 'slug' consisting of letters, numbers, underscores, "
u"dots or hyphens.", 'invalid')
class MySlugField(SlugField):
"""A custom field where dots *are* allowed in the slug.
This is needed for backwards compatibility with my Plone weblog items.
"""
default_error_messages = {
'invalid': u"Enter a valid 'slug' consisting of letters, numbers, "
u"underscores, dots or hyphens.",
}
default_validators = [validate_slug]
class BlogEntryForm(ModelForm):
slug = MySlugField()
class Meta:
model = BlogEntry
class BlogEntryAdmin(admin.ModelAdmin):
form = BlogEntryForm
prepopulated_fields = {'slug': ['title']}
admin.site.register(BlogEntry, BlogEntryAdmin)
Now SlugFields
with dots can just be saved. Making sure they can also
be retrieved is easy. All you need to do is change “(?P<slug>[-\w]+)
” in
your URL pattern with “(?P<slug>[-\w.]+)
”.
(Note that by default dots are still filtered out by the script that
prepopulates the SlugField
. That’s okay for me: I only did this for
the old entries and can still insert the dot manually if I really want
to.)