pass parameter to view function from jinja templates in flask [duplicate] - flask

I have an endpoint that takes a value in the url and produces some content that will be inserted into a div. I want to build the url with url_for using a JavaScript variable. However, $variable1 is passed as a string, rather than the value of variable1. How can I pass the value of a JavaScript variable to url_for?
function myFunction() {
var variable1 = "someString"
$('#demo').load(
"{{ url_for('addshare2', share = '$variable1') }}"
);
}

Sometimes I use the following workaround with a temporary placeholder string:
var variable1 = "someString";
$('#demo').load(
"{{ url_for('addshare2', share='ADDSHARE2') }}".replace("ADDSHARE2", variable1)
);
It doesn't feel quite right and I'm still looking for a better solution. But it does the job.

You can't evaluate JavaScript in Jinja. You're trying to generate a url on the server side while Jinja is rendering, but you're referencing a variable that is only available in the JavaScript running on the client browser.
Building the url on the client side is the most straightforward fix. (I don't know what your route looks like, so here's an example.)
$('#demo').load('/url/for/addshare2/' + variable1);
However, this isn't very useful because you can't use url_for, so you have to hard-code the urls. This is a good sign that what you want is an AJAX endpoint that you pass parameters to, rather than an endpoint that contains values.
#app.route('/addshare2', methods=['POST'])
def addshare2():
share = request.json['share']
...
return jsonify(result=...)
Now you can generate the url with url_for, and pass the parameters as form data.
$.post(
'{{ url_for('addshare2') }}',
{share: variable1},
function (data) {
// do something with data on successful response
}
);

It's possible to send a variable in Jinja by making a template filter to unquote the text returned by url_for()
add this to your app.py:
from urllib.parse import unquote as urllib_unquote
#app.template_filter('unquote')
def unquote(url):
safe = app.jinja_env.filters['safe']
return safe(urllib_unquote(url))
then on template do:
function myFunction() {
var variable1 = "someString"
$('#demo').load(
`{{ url_for('addshare2', share = '${variable1}')|unquote }}`
);
}
this will do the trick.
More on custom template filters: https://flask.palletsprojects.com/en/2.1.x/templating/#registering-filters

Related

Django: pass some paremeter to view in Django urls

I want to pass some string for some urls to my views in django
Suppose i have
path('someurl/', someview , name='someurl'),
I want to pass some string to someview, when this url is called so is this possible
path('someurl/', someview(somevar="test") , name='someurl'),
and then i have the view
def someview(request, somevar):
access somevar here
Is this possible in Django urls.
If you wish to accept parameter from the client, update your path as below:
path('someurl/<str:somevar>/', someview , name='someurl')
And view now can accept extra parameter:
def someview(request, somevar):
# now you can use somevar
With this definition, if client requests somevar/urlparam/, "urlparam" will be passed to you view function.
Otherwise if you want to provide your own argument, Django doesn't provide the way to do it directly in url definition. But, since that variable is your own one, why don't assign (or compute) that in view? I mean:
def someview(request):
somevar = "test" # or you may call some function for dynamic assignment
# now somevar exists in this scope, so you can use it as you want
yes it is possible. You need to define those parameters in the url as pseudo path:
path('articles/<int:year>/<int:month>/', views.month_archive),
There is also an option to use request.GET and request.POST to access the optional parameters list in the url:
request.POST.get('<par name here>','<default value here>')
request.GET.get('<par name here>','<default value here>')
Another thing you may find useful is this question.

how to pass a template's data to another template using iron router (not on query parameter)

I m new to iron router and want to pass one template'data to the calling template through Router.go() method. But i found it can be pass through query but i don't want to use query as my data is large JSON object.
So, is there a way to pass data from one template to another template using iron-router.
any help would be highly appreciated.
Save it to some local collection then use the ID in the url is one way.
JSONCollection = new Mongo.Collection('some_json');
Template.yourTemplate.events({
'click button[data-action="go-to-next"]': function (e, template) {
var id = JSONCollection.insert(template.data);
Router.go('yourroute', { _id: id });
}
});
Then your url will just contain the id.
/yourroute/:someIdHere
Use Session.set() before calling Router.go() and Session.get() on another template. This approach doesn't require round trip to database but be sure to not flooding Session object as it will persist throughout browser session.

Django passing parameter with AJAX

I am trying to pass parameters to Django view but I couldn't decide what is the best way to do it.
I am making an AJAX call and my javascript code is
url = "/review/flag/code/"+ code +"/type/" + type + "/content/" + content + "/";
$.getJSON(url, somefunction);
The corresponding url for this call
(r'^rate/code/(?P<code>[-\w]+)/type/(?P<type>[-\w]+)/content/(?P<content>[-\w]+)/$', 'project.views.flag_review'),
And I can get the parameters in my view such that
def rate_review(request,code,type,content):
....
My question is because content comes from a textarea it may involve many escape chars and passing it like above causes problems due to regular expression.
Is there any way if I pass the parameters like www.xx.com/review/rate?code=1&type=2&content=sdfafdkaposdfkapskdf... ?
Thanks
If the content variable is input through a textarea input field in a form, you should probably be using the HTTP POST method for submitting the data. You would get something like:
url = "/review/flag/code/"+ code +"/type/" + type;
$.post(url, {'content': content}, somefunction, 'html');
(r'^rate/code/(?P<code>[-\w]+)/type/(?P<type>[-\w]+)/$', 'project.views.flag_review'),
def rate_review(request,code,type):
content = request.POST['content']
...
Sure, in your rate_review function you can access request.GET and access those paramters:
/rate/code/?foo=bar
def rate_review(request):
request.GET['foo']

Django: grabbing parameters

I'm having the hardest time with what should be super simple. I can't grab the passed parameters in django.
In the browser I type:
http://localhost:8000/mysite/getst/?term=hello
My url pattern is:
(r'^mysite/getst/$', 'tube.views.getsearchterms')
My View is
def getsearchterms(request):
my_term = some_way_to_get_term
return HttpResponse(my_term)
In this case it should return "hello". I am calling the view, but a blank value is returned to me. I've tried various forms of GET....
What should some_way_to_get_term be?
The get parameters can be accesses like any dictionary:
my_term = request.GET['term']
my_term = request.GET.get('term', 'my default term')
By using arbitrary arguments after ? and then catching them with request.GET['term'], you're missing the best features of Django urls module : a consistent URL scheme
If "term" is always present in this URL call it must be meaningful to your application,
so your url rule could look like :
(r'^mysite/getst/(?P<term>[a-z-.]+)/', 'tube.views.getsearchterms')
That means :
That you've got a more SEO-FRIENDLY AND stable URL scheme (no ?term=this&q=that inside)
That you can catch your argument easily in your view :
Like this
def getsearchterms(request,term):
#do wahtever you want with var term
print term

Pass session data onto URL

I have some information that is set in the sessions, and I was wondering if it's possible to pass this info onto the URL for the view that uses this session data. I want this to be working in such a way that if the user bookmarks the page from that view, the session data is used to pass the variables onto the view. How can I do this?
I'm having a filter view so I want the currently selected filters displayed on the URL...sorta like www.mysite.com/filter1/filter2/filter3/ then if filter2 is cleared I'll have www.mysite.com/filter1/filter3/
Currently my URLConf for the filter view looks like this:
(r'^filter/$', 'filter'),
(r'^filter/(?P<p>\d{2})/$', 'filter'),
As you say, propagate the data on the url, rather than in session. But use the query-string - not the path, as you seem to suggest in your question.
There is no magic way to do this - you'll have to manually append the variables to all urls. You can however wrap the url-creation in a function, to make this more manageable. Eg.:
$GLOBALS['url_state'] = array();
function url($base, $params = array()) {
global $url_state;
$q = http_build_query(array_merge((array) $url_state, $params));
return $q ? "$base?$q" : $base;
}
function define_url_state($name, $default = null) {
global $url_state;
if (isset($_GET[$name])) {
$url_state[$name] = $_GET[$name];
} elseif ($default !== null) {
$url_state[$name] = "$default";
}
}
If you use this to build all your urls in the application, you can now easily make a variable "sticky". Eg. at the top of your page, you could use it like this:
define_url_state('page', 1);
And further down the page, you can generate urls with url(). You would then get either the default value (1) or whatever the user passed to the page's $_GET.
In django you don't use $_GET, but request.GET
lets say your url is http://example.com?filter=filter1&filter=filter2&filter=filter5
you can get the filter names in a view using getlist() like this:
def some_view(request):
filters = request.GET.getlist('filter')
so you URL conf (urls.py) will look something like this:
from django.conf.urls.defaults import *
urlpatterns = patterns('',
url(r'^filters/$', 'your_app.views.some_view', name='filter_view'),
)