Pyramids route_url with additional query arguments - python

In Pyramids framework, functions route_path and route_url are used to generate urls from routes configuration. So, if I have route:
config.add_route('idea', 'ideas/{idea}')
I am able to generate the url for it using
request.route_url('idea', idea="great");
However, sometimes I may want to add additional get parameters to generate url like:
idea/great?sort=asc
How to do this?
I have tried
request.route_url('idea', idea='great', sort='asc')
But that didn't work.

You can add additional query arguments to url passing the _query dictionary
request.route_url('idea', idea='great', _query={'sort':'asc'})

If you are using Mako templates, _query={...} won't work; instead you need to do:
${request.route_url('idea', idea='great', _query=(('sort', 'asc'),))}
The tuple of 2-tuples works as a dictionary.

Related

Why urls order is important in django for different named urls?

I have two urls in my urls.py file
url('to_quotation/$', views.to_quotation, name='to_quotation'),
url('turn_into_quotation/$', views.turn_into_quotation, name='turn_into_quotation'),
and i have two view for them in views.py. When i make an ajax call to 'turn_into_quotation' url, 'to_quotation' view works. But if i changed my urls.py as:
url('turn_into_quotation/$', views.turn_into_quotation, name='turn_into_quotation'),
url('to_quotation/$', views.to_quotation, name='to_quotation'),
it works properly.
What is the reason for that?
You are missing the ^ at the beginning of the regex. Change it to:
url(r'^to_quotation/$', views.to_quotation, name='to_quotation'),
url(r'^turn_into_quotation/$', views.turn_into_quotation, name='turn_into_quotation'),
Without the ^, to_quotation/$ matches to_quotation/ and also turn_into_quotation/. In that case, the order matters, because Django will use the first URL pattern that matches.
If you're using a recent version of Django, you could use path() instead, and avoid regex gotchas.
path('to_quotation/', views.to_quotation, name='to_quotation'),
path('turn_into_quotation/', views.turn_into_quotation, name='turn_into_quotation'),
#Alasdair's answer is amazing~ I'd like to attach more infomations:
Django use regex-like syntax to match it and split url's argument:
^to-quotation/<id: int>/$`
It will: 1. try to match the url, 2. try to split its argument from url, and here it split int-value to id.
So it is easy to know, in the url's settings, it is important to hold each sub-url cannot match another.

QueryString in Django

I need one small help. I have one django application already with me and everything is working fine. Now requirement is without making change in existing functions we want to pass urls parameter as a query string
path('my-app/', include('myapp.urls', namespace='myapp')),
# I added this line because I want to use dcid as a querystring
url(r'^my-app/(?:(?P<dcid>\w+)/)',include('myapp.urls', namespace='myapp')),
and my function is already written like this
def orders_b2b_open_list_pageable(request):
We don't want to change in above functions but we want dcid in query string. How can we achieve that
I am doing this but when requesting like this
http://localhost:8002/my-app/1/orders/b2b/open/pageable/
I am getting following error
Thank You in advance
There's no need to parse it in your urls.py, that would change your function signiture.
You can handle it in your view, by pulling the querystring value from the request:
def orders_b2b_open_list_pageable(request):
dcid = request.GET.get('dcid', None)
...

How to deal with params in URL schema in Django application

As we know most URL schemes base their URL syntax on this nine-part general format:
<scheme>://<user>:<password>#<host>:<port>/<path>;<params>?<query>#<frag>
I know I can get the query strings in Django request.GET dict. But how to get parameters? It seems HttpRequest in Django can not deal with params defined in URL.
For example: http://www.example.com/hello;param1=aaaa;param2=bbbb
Is there any way to extract params like this in Django without writing own regex in url pattern.
Any help will be appreciated.
The path segment parameters you're talking about were defined in RFC 2396. This RFC has been obsolete since 2005. The new standard, RFC 3986, does not define a specific way to define path segment parameters. The relevant section states:
Aside from dot-segments in hierarchical paths, a path segment is
considered opaque by the generic syntax. [...] For
example, the semicolon (";") and equals ("=") reserved characters are
often used to delimit parameters and parameter values applicable to
that segment. [...] Parameter types may be defined by scheme-specific
semantics, but in most cases the syntax of a parameter is specific to
the implementation of the URI's dereferencing algorithm.
Django uses the new standard and does not define any specific way to parse path segment parameters. However, Python defines the urlparse() function, which parses the url according to RFC2396. You can use this to extract the path parameters:
from urllib.parse import urlparse # urlparse.urlparse on Python 2
params = urlparse(request.path).params
to capture params you've to define url patterns as per that.
lets assume your url is http://myurl.com/mydashboard/250?sort=-1&q=this so here 250 is param which you want.
To capture the same you've to define url like below
url(r'^mydashboard/(?P<weeknum>\d+)/$',
mydashboard, name='mydashboard'),
and now the view definition of mydashboard will have another input param like below
def nagdashboard(request, weeknum):
And to get GET params or POST params you can use.
request.GET.get('sort')
For further reading on patterns refer to here

How to pass in multiple parameters to web.py's render

I am using Jinja2 with web.py and have come across what seems to be a simple problem. I am rendering my paramertized html files and can't seem to figure out how to pass in multiple parameter=value pairs without typing each on in as arguments. I tried passing in a dict and list of strings with no success.
If I want to render home.html which has five parameters that need values, how can I pass in their values without having to type param1=value1, param2=value2 as arguments to the reder.home() function?
I was hoping something like this would work:
from web.contrib.template import render_jinja
render = render_jinja('templates', encoding = 'utf-8',)
p = {}
p['param1'] = 56
p['param2'] = 'something'
...
render.home(p)
PS. the web.py template examples seem to only cover the single param example.
You can use dictionary expansion, like so
render.home(**p)

How to pass multiple values for a single URL parameter?

Is it possible to pass multiple values for a single URL parameter without using your own separator?
What I want to do is that the backend expects an input parameter urls to have one or more values. It can me set to a single or multiple URLs. What is a way to set the urls parameter so it can have multiple values? I can't use my own separator because it can be part of the value itself.
Example:
http://example.com/?urls=[value,value2...]
The urls parameter be set to just http://google.com or it can be set to http://google.com http://yahoo.com .... In the backend, I want to process each url as a separate values.
http://.../?urls=foo&urls=bar&...
...
request.GET.getlist('urls')
The following is probably the best way of doing it - ie, don't specify a delimited list of URLs, rather, use the fact you can specify the same param name multiple times, eg:
http://example.com/?url=http://google.co.uk&url=http://yahoo.com
The URL list be then be used and retrieved via request.GET.getlist('url')

Categories

Resources