M docs/release_notes.rst => docs/release_notes.rst +1 -0
@@ 38,6 38,7 @@ django-wiki 0.2 (dev)
* Added Django 1.10 support #563
* Fix duplicate search results when logged in #582 (duvholt)
+ * Do not allow slugs only consisting of numbers #558
* Fix memory leak in markdown extensions setting #564
* Updated translations - Languages > 90% completed: Chinese (China), Portuguese (Brazil), Korean (Korea), French, Slovak, Spanish, Dutch, German, Russian, Finnish.
* Taiwanese Chinese added (39% completed)
M wiki/forms.py => wiki/forms.py +29 -1
@@ 9,7 9,9 @@ from itertools import chain
from django import forms
from django.apps import apps
from django.contrib.auth.forms import UserCreationForm
+from django.core import validators
from django.core.urlresolvers import Resolver404, resolve
+from django.core.validators import RegexValidator
from django.forms.widgets import HiddenInput
from django.utils import timezone
from django.utils.html import conditional_escape, escape
@@ 32,6 34,32 @@ except ImportError:
return(x)
+validate_slug_numbers = RegexValidator(
+ r'^\d+$',
+ _("A 'slug' cannot consist solely of numbers."),
+ 'invalid',
+ inverse_match=True
+)
+
+
+class WikiSlugField(forms.SlugField):
+ """
+ In future versions of Django, we might be able to define this field as
+ the default field directly on the model. For now, it's used in CreateForm.
+ """
+
+ default_validators = [validators.validate_slug, validate_slug_numbers]
+
+ def __init__(self, *args, **kwargs):
+ self.allow_unicode = kwargs.pop('allow_unicode', False)
+ if self.allow_unicode:
+ self.default_validators = [
+ validators.validate_unicode_slug,
+ validate_slug_numbers
+ ]
+ super(forms.SlugField, self).__init__(*args, **kwargs)
+
+
User = get_user_model()
Group = apps.get_model(settings.GROUP_MODEL)
@@ 313,7 341,7 @@ class CreateForm(forms.Form, SpamProtectionMixin):
self.urlpath_parent = urlpath_parent
title = forms.CharField(label=_('Title'),)
- slug = forms.SlugField(
+ slug = WikiSlugField(
label=_('Slug'),
help_text=_(
"This will be the address where your article can be found. Use only alphanumeric characters and - or _. Note that you cannot change the slug after creating the article."),
M wiki/tests/test_views.py => wiki/tests/test_views.py +17 -0
@@ 3,7 3,9 @@ from __future__ import absolute_import, print_function, unicode_literals
import pprint
from django.contrib.auth import authenticate
+from django.utils.html import escape
from wiki import models
+from wiki.forms import validate_slug_numbers
from wiki.models import reverse
from .base import ArticleWebTestBase, WebTestBase
@@ 154,6 156,21 @@ class CreateViewTest(ArticleWebTestBase):
'Content'
) # on level 2')
+ def test_illegal_slug(self):
+
+ c = self.c
+
+ # A slug cannot be '123' because it gets confused with an article ID.
+ response = c.post(
+ reverse('wiki:create', kwargs={'path': ''}),
+ {'title': 'Illegal slug', 'slug': '123', 'content': 'blah'}
+ )
+ self.assertContains(
+ response,
+ escape(validate_slug_numbers.message)
+ )
+
+
class DeleteViewTest(ArticleWebTestBase):