django how to pass parameter from url to view - python

I'm trying to append a parameter no_rep at the end of my question url as a signal to show different views. I'm using Django 1.8 and following the url pattern from askbot.
This is the url.py:
url(
(r'^%s(?P<id>\d+)/' % QUESTION_PAGE_BASE_URL.strip('/') +
r'(%s)?' % r'/no-rep:(?P<no_rep>\w+)'),
views.readers.question,
name='question'
),
I'm trying to show different displays depending on the value of no_rep in my url.
This is the view:
def question(request, id, no_rep):
if no_rep == '1':
request.session['no_rep'] = True
else:
request.session['no_rep'] = False
I couldn't find information on what the +,%,? do, which is probably where the problem is. Could someone explain how the regex work with the base url? When I enter the url http://localhost:8000/question6/test-question/no_rep:1, request.session['no_rep'] should be set to true, but it's not. What am I missing?

Your url looks like this after all substitutions (%): r'^question(?P<id>\d+)/(/no-rep:(?P<no_rep>\w+))?', so:
1. Missing part for test-question
2. You have odd grouping around named group no_rep (which is legal, but not recommended)
So for url like http://localhost:8000/question6/test-question/no_rep:1 your url pattern should look like this:
r'^%s(?P<id>\d+)/test-question/(?:no_rep:(?P<no_rep>\d+))?' % QUESTION_PAGE_BASE_URL.strip('/') (you can change \d+ in the last group for \w+ if you want letters to match too).
About non-capturing groups (?:...) and meaning of + and ? you can read in the documentation of Python re module.

Related

Mapping URL path parameters with Flask

I am trying to map the path parameter form part of the request URL:
example
I am doing this but it doesn't work:
#app.route("/people/:<string:id>", methods=['GET'])
def api_search_a_person(id):
return Id
Does anyone know how to get the value after the ":" (string "123456-7" in the example)
: is a special URI character because it's used to define the protocol or port, so it's likely that your browser URI encodes the character.
Do you really need this character anyway ? Can't you simply remove it (http://host.net/people/123456-7), or use URI parameters instead http://host.net/people/?123456-7 ?
If you really want to use a :, escape it on both ends (the escape character is %3A).
Try this:
#app.route("/people/:<string_id>", methods=['GET']) # notice _ instead :
def api_search_a_person(string_id): # extracts the string_id from the request url
return string_id # returns the mapped string_id
It's unclear why you used <string:id> with : inside.
And also what Id represents in the return (maybe you meant id from the method parameter ...

Django domain + regex parameter not working on production machine

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!
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', '')

Django urlpattern with infinite number of parameters

Is it possible to define Django urlpattern, which would get any number of same type parameters and pass them to a view?
Lets say I want to create a page which gets a list of numbers from url and sums them. So these would be valid urls:
/sum/10/99/12/
/sum/1/2/3/4/5/6/7/8/9/
/sum/3/
I guess that view could look like this:
def sum_view(request, *args):
return render(request, 'sum.html', {'result': sum(args)})
Question is how should urlpattern look like? Maybe something like this:
url(r'^sum/((\d+)/)+$', views.sum_view)
But this way view gets only last number repeated twice: args == ('1/', '1'). What is the correct regular expression to get all the numbers passed ot the view?
You could capture a single argument, e.g. '1/2/3/4/5/6/7/8/9/'
url(r'^sum/(?P<numbers>[\d/]+)$', views.sum_view)
The split the list in the view.
def sum_view(request, numbers):
processed_numbers = [int(x) for x in number.split('/') if x]
...
Django's urlpatterns are based on python's regexps so there is no way of catching all data from repeating group. Check this question for explanation.
You will have to split and process them by yourself (like #Alasdair suggests).

Django URL regex "is not a valid regular expression" error

I'm having a bit of trouble configuring the following url. I want it to be able to match a pages which start off with a category and then finish with a slug, examples:
/category1/post1/
/category2/post2/
/category3/post3/
/category1/post4/
/category2/post5/
I've tried many different methods with no success... I always get an "is not a valid regular expression" error.
This is how I thought it should work:
url(r'^(?P<category1|category2|category3>[\w\-]+)/(?P<slug>[\w\-]+)/$', blog_post, name = 'blog_post'),
I am fairly new to regex and trying to learn so any help on this one with an explanation would be much appreciated :)
Your pattern is incorrect; you are putting the alternative values in the wrong place. You put them in the name of the group:
(?P<category1|category2|category3>...)
Put them in the part the name is supposed to match instead:
(?P<category>category1|category2|category3)
Making the full registration:
url(r'^(?P<category>category1|category2|category3)/(?P<slug>[\w\-]+)/$', blog_post, name='blog_post'),
I'm assuming your blog_post callable looks something like:
def blog_post(category, slug):

Python: Having trouble understanding regex

I was going through the django tutorial and though now almost everything there seems pretty clear, I am having trouble understanding the regex while matching the urls :
r'^(?P<poll_id>\d+)/$
what does (?P<poll_id>\d+) do ?
I am understanding that after stripping off the "34/" from "polls/34/", The polls.url is being called and there the keyword urlpatterns is being looked for , but how does poll_id get this value 34 ?
I know only a bit of regex, so thats why it might be hard for me to read.
Also, here is the reference that I am using for this question :Tutorial Part3
It's a regex that takes the poll_id (a number) as a variable.
The corresponding view is:
def detail(request, poll_id):
return HttpResponse("You're looking at poll %s." % poll_id)
Now when you go to example.com/polls/34/, it knows you are looking for poll number 34, and it brings that in to the view as the poll_id.
So in your view, poll_id = 34. This allows you to display or manipulate this specific poll.
Essentially the point of the regex in this case is to allow you to view a large number of specific polls without having to create an explicit url for each one.
To clarify, this regex is saying take any number \d+, save it as poll_id, and proceed to this view with that poll_id.
To support for Dan Hoerst 's answer: yup, django uses regular expression to extract the poll_id for the view. The underneath of this is:
import re
r = re.compile(r'^poll/(?P<poll_id>\d+)/$')
r.match('poll/132/').groups() # ('132',)

Categories