I have a route:
#app.route("/login/<user>/<timestamp>")
def user(user, timestamp):.
But, I need it in this form -
#app.route("/login/<user><timestamp>")
def user(user, timestamp):.
i.e without the slash('/').
Is there any way to do it ?
Short answer: It is possible given the two parameters have a non-overlapping pattern. By giving it a wildcard-pattern however (you did not specify the converter). It will result in the fact that all content is handled to the user. That being said, it is advisable to have a clear separator.
As is specified in the documentation, you can define variables by writing them like HTML tags, like <var>, you can also specify a converter, like <converter:var>. If you do not specify a converter, the parameter is assumed to be a string that can not contain slashes.
There are however other converters, like int, float, path and uuid.
If the patterns are written in such way that it is clear when the first pattern ends, and the second pattern begins, then it this can be handled. For example:
#app.route("/login/<int:day><user>")
can work, given user can not start with a digit, since here once the sequence of digits ends, Flask will parse the <user> parameter.
By writing #app.route("/login/<user><timestamp>") however, the two patterns are overlapping: if we do not have a parsing strategy any split could be a valid one. Since the engine is greedy if I recall correctly, in practice it will result in the fact that user takes all characters, and timestamp none.
Since the default string does not include a slash, we know that the slash acts as a clear separator, since it is not included in both variables in your example.
I used to pass data through django URL while passing #character is not able to pass through urls.py, I am using pattern as
url(r'^pass/(?P<sentence>[\w|\W]*)/$',pass)
I tried with these pattern also
url(r'^pass/(?P<sentence>[a-zA-Z0-9-/:-?##{-~!^_\'\[\]*]*)/$',pass)
Thanks in advance.
The "#" character marks inline anchors (links within the same page) in a URL, so the browser will never send it to Django.
For example, if the URL is /something/pass/#test/something-else/ the browser will sent only /something/pass/ to the server. You can try /something/pass/%23test/something-else/ instead, 23 is the hexadecimal ascii code for # - not pretty (ugly by ugly just pass it as a get variable instead).
There is nothing you can do on the Django side - you better avoid characters with special meanings in the URL path when designing your routes - of course it is a matter of taste, but I really think that strings passed in the URL path should be "slugfied" in order to remove any funny character.
Browsers won't send the url fragment part (ends with "#") to servers. Why not converting your data to base64 first, then pass the data via url.
RFC 1808 (Relative Uniform Resource Locators) : Note that the fragment identifier (and the "#" that precedes it) is
not considered part of the URL. However, since it is commonly used
within the same string context as a URL, a parser must be able to
recognize the fragment when it is present and set it aside as part of
the parsing process.
It seems Flask doesn't support routes with a URI encoded component. I'm curious if I'm doing something wrong, or if there is a special flag I need to include.
My route looks something like this:
#app.route('/foo/<encoded>/bar/')
def foo(encoded):
# ...
pass
The URL that this should match can look like these:
http://foobar.com/foo/xxx/bar/ # matched correctly, no URI component
http://foobar.com/foo/x%2Fx%2Fx%2F/bar/ # not matched correctly, URI component
Former URL works, latter spits out a lovely 404.
Thanks!
Add path to your url rule:
#app.route('/foo/<path:encoded>/bar/')
Update per comment: The route API docs are here: http://flask.pocoo.org/docs/api/#flask.Flask.route. The underlying classes that implement the path style route converter are here: http://werkzeug.pocoo.org/docs/routing/#custom-converters (this is one of the really nice parts of pocoostan.) As far as the trailing slashes, there are special rules that amount to:
If a rule ends with a slash and is requested without a slash by the
user, the user is automatically redirected to the same page with a
trailing slash attached.
If a rule does not end with a trailing slash and the user request the
page with a trailing slash, a 404 not found is raised.
Also keep in mind that if you are on Apache and are expecting a slash-trailed url, ie a bookmarklet that submits to http://ex.com/foo/<path:encoded>/bar and encoded gets something with double slashes, Apache will convert multiple slashes to a single one.
I'm having some trouble sending along more than one variable to the view.
my urls.py is as follows:
urlpatterns = patterns('',
url(r'^rss/(?P<anything>[^/]+)/$', 'rss.rssama.views.makerss', name='anything'),
url(r'^$', 'rss.rssama.views.home'),
)
views.py
def maakrss(request, anything):
So now it takes from www.mydomain.com/rss/[anything]/ and sends 'anything' to my view. However I also want it to send along another string to views.py, like:
www.mydomain.com/rss/[anynumber]/[anystring]/
I tried this but that didn't work:
url(r'^rss/(?P<anynumber>[^/]+)/(?P<anystring>[^/]+)/$', 'rss.rssama.views.makerss', name='anynumber', name2='anystring'),
But this doesn't work, it gives this error: keyword argument repeated (urls.py, line 17)
So my question: How can I make it to give along two string from the url?
To begin with, the regex part should look like this:
r'^/rss/(?P<anynumber>\d+)/(?P<anystring>.+)/$'
Those strings inside the <...> parts allow you to give a name to whatever the regex matches. Django will then use that name to pass the value to your function. Therefore your function must have an argument with the same name. In this case, Django will take the value called anynumber and use that value for the parameter of your function that is called anynumber. The same goes for anystring, and this system frees you from worrying about what order the arguments of your function are in.
\d+ will match one or more numeric characters (digits). It's good practice to limit the regex to match only numbers if that's what you intend to catch, rather than any character and hope that only numbers appear. If you wanted to limit the digits part to a certain number of digits, you could use \d{1,4} to take from one to four digits.
The next part, (?P<anystring>.+) will catch a string consisting of one or more of any characters. This would actually match something like 'letters/moreletters', including the slash. There are a number of "special sequences" in Python regex that might help. To match only digits, letters, and the underscore character, use \w, as in (?P<anystring>\w+). To be more lax but ignore whitespace or any other non-sense, (?P<anystring>[a-zA-Z1-9:;_{}\[\]] to catch a whole slew of characters. Make sure to escape anything that might be a special character in a regex. However, be conservative. If you allow too many options who knows what sorts of bugs you'll have to work out later.
Now onto name parameter of the url function. That name is not what it will pass the caught patterns to your functions as. It's a name for a particular class of invocation of your view function that can be used as a short-hand in other contexts like, the template tag {% url view-name arg1 arg2 %}. So, the name you have already, "anything", refers to a call to your view function, passing it one keyword argument that happens to be called anything. For the case where you want to pass two strings, give that a name like "rss-number-string" to signify the arguments you want to take, or a name that refers to the special function your view will be performing with that combination.
I use multiple names for the same function all the time, and the key is this:
def makerss(request, anystring=None, anynumber=None):
By giving the parameters default values, it allows you to use the same function in different ways. In this case, the function can be used when you only want to pass a value for anystring, or when anystring and anynumber should have values.
I know this is a lot of different points, so I'll try to put it all together so you can see how it might work. To have two urls, one which catch a string and passes it on, and another which catches a number, a slash, and then a string, but both point to the same view function, you could use this:
urlpatterns = patterns('',
url(r'^rss/(?P<anystring>\w+)/$', 'rss.rssama.views.makerss', name='rss-anystring'),
url(r'^rss/(?P<anynumber>\d+)/(?P<anystring>\w+)/$', 'rss.rssama.views.makerss', name='rss-number-string'),
url(r'^$', 'rss.rssama.views.home'),
)
With a view function something like this:
def makerss(request, anystring=None, anynumber=None):
if anystring:
if anynumber:
#Do something with the string and the number
else:
#Do something with just the string
Please let me know if this helps. Also, Django rocks, so kudos!
Python Regex Library Docs
You don't really need to give two name arguments for this. I mean, you already have the variable names inside regex. The actual problem is, you cannot give two name arguments, so you can do this instead:
url(r'^rss/(?P<anynumber>[^/]+)/(?P<anystring>[^/]+)/$', 'rss.rssama.views.makerss',name='something'),
EDIT:
using the urlConf above you can create corresponding view as:
def makerss(request, anynumber, anystring):
What is name2 supposed to be? The url function takes a name parameter, which is the name of the URL when you reverse it, but you can't put random extra functions.
Otherwise, you have the right syntax for sending two elements to a view. Of course, since you've masked the variable names and not provided the actual error or traceback, we have no way of knowing what really is going wrong.
Is there a way in Django to accept 'n' parameters which are delimited by a '/' (forward slash)?
I was thinking this may work, but it does not. Django still recognizes forward slashes as delimiters.
(r'^(?P<path>[-\w]+/)$', 'some.view', {}),
Add the right url to your urlpatterns:
# ...
("^foo/(.*)$", "foo"), # or whatever
# ...
And process it in your view, like AlbertoPL said:
fields = paramPassedInAccordingToThatUrl.split('/')
Certainly, Django can accept any URL which can be described by a regular expression - including one which has a prefix followed by a '/' followed by a variable number of segments separated by '/'. The exact regular expression will depend on what you want to accept - but an example in Django is given by /admin URLs which parse the suffix of the URL in the view.