4

I would like to create a profile page for every account created. Once created the user profile can be accessed like

http://example.com/username

But before creation I should validate that the url is already available and not taken by existing url patterns. For ex: There will be a page like

http://example.com/about

Now "about" is not a valid user. But it is a valid url pattern. I should be able to prevent a user creation with a name 'about'. For that I need to check the url patterns in addition to check whether a user with that name already exists. How to do this?

An easy way out would be to have a url pattern like the following for the profile page: http://example.com/user/username

But I've a strong requirement to have profile page like the following http://example.com/username

2
  • Can you show some of the code you currently use to validate the url? I'd say that something like if 'about' in url: return False might be enough, but maybe I misunderstand the question. Commented Jun 26, 2012 at 12:34
  • For example in urls.py, I've url(r'^admin/', include(admin.site.urls)), Now, the view function should not allow to create a user with name 'admin' although there is no existing user with that name. Commented Jun 26, 2012 at 12:49

5 Answers 5

2

You can simply try to resolve the address to a view:

from django.core.urlresolvers import resolve
from myapp.views import user_profile_view

try:
    my_view = resolve("/%s/" % user_name)
    if my_view == user_profile_view:
        # We match the user_profile_view, so that's OK.
    else:
        # oops, we have another view that is mapped on that URL
    # you already have something mapped on this address
except:
    # app doesn't have such path

EDIT:

you can also make the check in a different way:

def user_profile_view(request, user_name):
    # some code here

user_profile_view.name = "User Profile View"

and then the check above could be:

if getattr(my_view, "name", None) == "User Profile View":
    ...
Sign up to request clarification or add additional context in comments.

10 Comments

This doesn't work! It always goes to the except condition. :-(
Oh, right. You just have to check the view name, returned by this
url(r'^admin/', include(admin.site.urls)) try: urlresolvers.resolve("/%s" % 'admin') match = "Path already present" except: match = "doesn't match" I always get 'doesn't match'
Yep, see my updated answer. You have a catch-all view handler for users. So you just have to check if this URL is processed by User profile view (which means that the wildcard matches), or if it is handled by another view
It always goes to the except condition! urlresolvers.resolve always raises exception.
|
1

you can add custom form field validation. Look at this post. Django and Custom Form validation

raise forms.ValidationError(u'please choose another username') check and raise errors.

Or you can try setting the following as url for your users, example.com/user/<username>/

edit 1 : you can use this as a list of all invalid usernames

Comments

0

I don't think you can check this with django.core.urlresolvers.resolve. Note that it just checks for the pattern for fixed url and not variable part of your url. In your case, you will most likely have 'username' as variable parameter that is passed to view. Pattern for this will match for non-existing username also. So the checking patterns is not good solution.

Better method will be separating out static or other pages in different namespace. e.g. http://example.com/static/about

Or you can have predefined keywords/reserved words for your site e.g. [ "about", ... ] and check it against username while creating user.

Comments

0

Put your username view at the end of urls.py, so that other url rules will be checked first.

Then the easiest way is to have a list of invalid user names which should be used in user registration validation.

def clean_username(self):
    INVALID_USERNAMES = ('about', 'admin', 'register', '...')

    username = self.cleaned_data['username']
    try:
        user = User.objects.get(username=username)
    except User.DoesNotExist:
        pass
    else:
        raise forms.ValidationError(u'%s already exists' % username )

    if username in INVALID_USERNAMES:
        raise forms.ValidationError(u'%s is not a valid username' % username )

    return username

Comments

0

firstly, a url rule for usernames:

url(r'^(?P<username>[-\w]+)/$', 'membership.views.profile', name='profile'),

making sure that a username doesn't conflict with an existing url rule is a little harder.

the way I usually handle this is by adding uniqueness to the url:

url(r'^user/(?P<username>[-\w]+)/$', 'membership.views.profile', name='profile'),

if you absolutely must have the url for profiles start with the username then you can try to rake the urls using a method like this one: https://stackoverflow.com/a/2094270/884453 and then make sure that username is both unique against other usernames and against routes

EDIT

as i was writing this someone posted a cool idea for a validator that makes a bunch more sense.

using from django.core.urlresolvers import resolve to check it for uniqueness is a great solution

from django.core.exceptions import ValidationError
from django.core.urlresolvers import resolve

def validate_unique_resolve(value):
    urlroute = True
    try:
        urlroute = resolve(path, urlconf)
    except urlresolvers.Resolver404:
        urlroute = False

    if urlroute != False :
        raise ValidationError(u'%s is a reserved url pattern' % value)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.