Staccato
Staccato

Reputation: 658

How to match a 'word' using regex in django/python

I'm using Django/Python and I want to be able to prevent the user from using these words: "login" and "logout" as their username. My current solution is to use a regular expression to check if their input contains the forbidden words (login, logout). If it matters, I'm using a custom user_model extended from AbstractBaseUser.

#models.py
username = models.CharField(max_length=14, blank=False, unique=True,
validators=[
validators.RegexValidator(
re.compile('^[^:;\'\"<>!@#$%|\^&\*\(\)~`,.?/=\-\+\\\{\}]? [\w]+$'),
#the line below is my regex for finding the words
re.compile(r'\blogout\b'))],

#variations i've tried are
#re.compile('\bword\b')
#re.compile(r'\b[^word]\b')
#re.compile(r'\Blogout\B')
#re.compile(r"\b(logout)\b")
#re.compile(r'(\bword\b)')
#re.compile('\blogout\b' or '\blogin\b')
#re.compile(r'\b'+'logout'+'\b')
#re.compile(r'^logout\w+$' or r'\blogin\b', re.I)
#re.match(r'\blogout\b','logout') 
#etc...
error_messages={'required':
                    'Please provide a username.',
                    'invalid': 'Alphanumeric characters only',
                    'unique': 'Username is already taken.'},
)

I've already read: Python's how-to Regular Expressions unless I missed something but I couldn't find a solution. I also tried but to no avail. My only alternative which I know works, is to implement the validation in the view:

#views.py
#login and logout are used by the system so are invalid for usernames
#updated
if clean['username'] == 'login' or 'logout':
   return HttpResponse('Invalid username')

But this is not ideal for me.

Upvotes: 0

Views: 1069

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1123520

You'll have to make it a separate validator; you are passing the second regular expression into the RegexValidator() object as a message.

Just use a simple function that validates the value; you don't need a regular expression here, you want to invalidate values instead. Writing a regular expression that matches only on a negative gets complicated and is not what you want to do here:

from django.core.exceptions import ValidationError

forbidden = {'login', 'logout'}

def not_forbidden(value):
    if value in forbidden:
        raise ValidationError(u'%s is not permitted as a username' % value)


username = models.CharField(max_length=14, blank=False, unique=True, validators=[
        validators.RegexValidator(r'^[^:;\'\"<>!@#$%|\^&\*\(\)~`,.?/=\-\+\\\{\}]? [\w]+$'),
        not_forbidden,
    ])

See Writing validators.

Upvotes: 1

Related Questions