1

I currently have a django view with a fairly simple search function (takes user input, returns a list of objects). For usability, I'd like the option of passing search paramters via url like so:

www.example.com/search/mysearchstring

Where mysearchstring is the input to the search function. I'm using regex to validate any alphanumeric or underscore characters.

The problem I'm having is that while this works perfectly in my development environment, it breaks on the live machine.

Currently, I am using this exact same method (with different regex patterns) in other django views without any issues. This leads me to believe that either.

1) My regex is truly bad (more likely)

2) There is a difference in regex validators between environments (less likely)

The machine running this is using django 1.6 and python 2.7, which are slightly behind my development machine, but not significantly.

urls.py

SEARCH_REGEX = '(?P<pdom>\w*)?' 
urlpatterns = patterns('',
....
url(r'^polls/search/' + SEARCH_REGEX,  'polls.views.search'),
...)

Which are passed to the view like this views. py

def search(request, pdom):
...

When loading up the page, I get the following error:

ImproperlyConfigured: "^polls/search/(?P<pdom>\w*)?" is not a valid regular expression: nothing to repeat

I've been scratching my head over this one for a while. I've attempted to use a few different methods of encapsulation around the expression with no change in results. Would appreciate any insight!

rob
  • 2,119
  • 1
  • 22
  • 41

1 Answers1

0

I would change it to this:

SEARCH_REGEX = r'(?P<pdom>.+)$' 

It's usually a good idea to use raw strings r'' for regular expressions in python.

The group will match the entire content of the search part of your url. I would handle query string validation in the view, instead of in the url regex. If someone tries to search polls/search/two+words, you should not return a 404, but instead a 400 status and a error message explaining that the search string was malformed.

Finally, you might want to follow the common convention for search urls. Which is to use a query parameter called q. So your url-pattern would be ^polls/search/$, and then you just handle the q in the view using something like this:

def search_page_view(request):

    query_string = request.GET.get('q', '')
Håken Lid
  • 22,318
  • 9
  • 52
  • 67
  • If not using raw strings were the issue, it would seem my other expressions should break as they are formatted exactly the same. But, I've got no other leads so I'll give it a shot. Thanks for the convention tips...I'll note them for the future, but this is a SU only tool, so I don't need to catch the 400's elegantly. I'll give this a shot this evening (Like I said, I have to test it on live server) and if it works, i'll accept. – rob Jun 08 '16 at 21:36
  • I'm not exactly sure what triggers the exception, since you haven't included a traceback. But the exception comes from django, not from `re`. It might be because of the final `?`, which I can't see any use for anyway. – Håken Lid Jun 08 '16 at 21:54
  • 1
    It turns out I was wrong about this being a django error. The root cause seems to be a bug in `re` that has been fixed in current versions of python. http://stackoverflow.com/questions/3675144/regex-error-nothing-to-repeat – Håken Lid Jun 08 '16 at 22:13
  • I'm going to attempt a more verbose expression to try to get around this bug, something like [A-Za-z0-9_.]* . Thanks again for finding that bug link, I was totally lost. – rob Jun 09 '16 at 13:22