Send parameters using URL syntax - python

I'm trying to use the audio player Timeside in Django 1.5. JavaScript function that handles loading the player receives this set of parameters,
loadplayer.js
loadPlayer function (analizerUrl, soundUrl, soundImgSize, itemId, visualizers, CurrentUserName, isStaffOrSuperuser)
In my template is the following script that handles launch
{% If item.file %}
loadPlayer('{% url 'item-analyze-xml' item.public_id %}',
"{% url 'item-export' item.public_id,"mp3" %}", undefined, '{{item.id}}', visualizers,
CURRENT_USER_NAME, //undefined if !user.is_authenticated
true); //true because superuser
{% Endif%}
URLs are configured as follows
url(r'^archives/items/download/(?P<public_id>[A-Za-z0-9._-]+)\.(?P<extension>'
+ export_extensions + ')$',
item_view.item_export,
name="item-export"),
url(r'^archives/items/(?P<public_id>[A-Za-z0-9._-]+)/analyze/xml/$',
item_view.item_analyze_xml,
name="item-analyze-xml"),
This worked in Django 1.4, attempt to update for be used in version 1.5. The problem is that I can not send the parameter MP3 here
"{% url 'item-export' item.public_id,"mp3" %}",
the view item_export is like this:
def item_export(self, request, public_id, extension):
When the player loads I get the following error:
Could not parse the remainder: ',' from 'pista.public_id,'
Which is the correct syntax for this on Django 1.5?
Using the name and equal solved this step
{% url 'item-export' public_id=item.public_id extension="mp3" %}
Seems like it is working but I have a new error:
NoReverseMatch at /pista/1/
Reverse for 'item-analyze-xml' with arguments '()' and keyword arguments '{u'public_id': ''}' not found.

I do not want to answer my own question but I've been searching and trying a lot and I found the solution.
{% Url 'impromusic-item-export' item.id 'mp3'%}
The first quotes refer to the name of the url(everybody know), item.id can be variable depends on the object, but if I write it in quotes it will be a string of characters wich not accept any value beyond which we assign.
That's my conclusion after 5 hours of searching but I can be wrong :) hope u understand me

Related

jinja2 include file with variable

I'm trying to refacto some pretty heavy template with jinja2 and I'm stucked on an include.
This is the behaviour i'm expecting :
<h1>{{ key }} </h1>
{% set file = key | include_text %}
{% include file %}
The custom filter returns a string like this one ::
texts/my_include.html
But instead I got this error:
jinja2.exceptions.TemplatesNotFound: Tried to select from an empty list of templates
Some hack I've already tried :
Place the templates in the same folder and remove the 'texts/' from the returned string
Add the path in the Env loader
But it keeps sending this error
I'm now wondering if jinja2 allows this implementation or if I'll have to keep this template the way it was (even if it takes a very long time to be generated).
Does someone know about some trick here ?
Well, for those who eventually met this problem in the futur, I've solved it by removing the unecessary single quotes and by sending some empty file from my custom filter when the condition is not verified... (my mistake)
Here is my custom filter :
#environmentfilter
def include_text(ctx, key):
res_dict = {
'key_value_1' : 'file_name_1',
'key_value_2' : 'file_name_2'
}
try:
return "texts/" + res_dict[key] + ".html"
except KeyError:
return "texts/empty.html"
Now, the first solution I was trying works fine.

trim() function in Python using Flask

Is there a function like trim() in python?
i use Flask miniframework and it doesn't accept:
selected_student = (request.args.get('student_form')).strip()
its error: AttributeError: 'NoneType' object has no attribute 'strip'
selected_student.replace(" ", "")
its error: AttributeError: 'NoneType' object has no attribute 'replace'
i need a function like trim() without coding a class/subclass or javascript
You're seeing the errors that you are seeing because there is no data being passed from your form to the Flask server. Your use of request is returning a None value type as opposed to a str.
You posted the following HTML mark up for your form:
<form action="/student" method='POST'>
<select name="student_form ">
{% for student in students_list %}
<option value="{{student}}">{{student}}</option>
{% endfor %}
</select>
<input type='submit' value='submit' />
</form>
So therefore you're going to need somewhere for Flask to pick up this data on the server side, for example:
#app.route('/student', methods=['POST'])
def receive_student_form_data:
my_selection = str(request.form.get('student_form')).strip()
print(my_selection)
Just to clarify why I've made my method in this way: I notice that you're using request.args.get() in order to retrieve the value sent by the form. This is incorrect.
request.args is used to retrieve key / value pairs from the URL.
request.form is used to retrieve key / value pairs from a HTML form.
So I'd suggest that you should use request.form.get('student_form') instead. If you really want to be certain that it is being cast as a str when retrieved by your Flask server, then you can cast it as a str as follows:
str(request.form.get('student_form'))
Then, as has been suggested by a few people already, you can use the .strip() method to remove any trailing spaces.
There is a strip() method. The error you get is because you are trying to run it on a NoneType object. You need to run it on a string object.
>>> s = 'some string '
>>> s.strip()
'some string'
There is also replace for strings:
>>> s.replace('some', 'many')
'many string '
The issue you encounter is related to something else. You end with a None object instead of what you are trying to get.

Python flask - Encoding links based on JSON varibale

I'm creating an application in Python flask and I'm struggling to encode my links. In my HTML template I'm calling data from JSON and based on a variable from JSON, I want to create a link to another page but the variables that have "space" in them, only take the first word and the link doesn't work as it should.
This is my JSON:
[
{
"team":"AFC Bournemouth"
},
{
"team":"Arsenal"
}
]
And this is my python:
#app.route('/<team>/')
def artist(team):
json_data=open('static/data.json').read()
data= json.loads(json_data)
urllib.quote_plus(data.team)
return render_template("team.html", team=team)
I'm trying to use "urllib.quote_plus" but I get an error
AttributeError: 'list' object has no attribute 'team'
I don't know how to fix it.
And this is my loop in html:
{% for data in results %}
<div class="team">
<p><a href=/{{ data.team }}>{{ data.team }}</a></p>
</div>
{% endfor %}
Before I used "urllib.quote_plus" the link for "Arsenal" worked perfect, but for "AFC Bournemouth" it only took the word "AFC".
That is strange that it is working correctly for "Arsenal". Actually you should iterate over the "data" because it is a list
Example:
#app.route('/<team>/')
def artist(team):
json_data=open('static/data.json').read()
data= json.loads(json_data)
data = [{'team': urllib.quote_plus(team['team'])} for team in data]
return render_template("team.html", results=data)
Another thing is that in render_template you are sending variable team and not results (changed in my example). This way it should be fine and work with your Jinja template.
Edit: changed list comprehension

How do I use Jinja2 filter on a block with argumets

I am trying to use jinja2 templates. I have custom filter called highlight, that takes string and language name and passes them to pyhments for code highlightning. I am trying to use it like this:
{% filter highlight("python") %}
import sys
def main():
pass
{% endfilter %}
But I get this error:
AttributeError: 'str' object has no attribute 'get_tokens'
Then I tried this:
{% filter highlight "python" %}
It does not work either.
There might be a trick via set block filtering and then pasting it back via {{ ... }}, but this technique is not merged in master source code yet, and seems too hacky for me.
So, is that even possible currently, or I am just doing it wrong?
EDIT: Here is filter:
#jinja2.contextfilter
def highlight(context, code, lang):
print("HIGHLIGHT")
print(code)
return jinja2.Markup(pygments.highlight(code, lexer=lang, formatter='html'))
I am an idiot, that was pygments error. By some mistake, I didn't see that last entry in stacktrace was from there.
You should use:
pygments.highlight(
code,
lexer=pygments.lexers.get_lexer_by_name(lang),
formatter=pygments.formatters.get_formatter_by_name('html')
)
instead of:
pygments.highlight(code, lexer=lang, formatter='html')

Using '#notfound_view_config' in Pyramid with 'renderer'

I'm unable to get my specified template to render when using #notfound_view_config as described in Pyramid Docs - Using Hooks.
views.py:
#notfound_view_config(renderer='templates/notfound.pt')
def notfound(request):
return Response('Not Found, dude', status='404 Not Found')
templates/notfound.pt:
<html xmlns="http://www.w3.org/1999/xhtml"
metal:use-macro="base">
<tal:block metal:fill-slot="content">
<!-- Example row of columns -->
<div class="row">
<div class="span12">
<h1>Error:</h1>
<p>Uh, oh... you snagged an error:</p>
<pre>"${request}"</pre>
<p>You can return to the homepage if you wish.</p>
</div>
</div>
</tal:block>
</html>
When hitting a page that doesn't exist, I see the message "Not Found, dude" on a blank page, but I expected to see my template with "Uh, oh... you snagged an error!" followed by the request information.
I suspect I'm reading this wrong:
The notfound_view_config constructor accepts most of the same
arguments as the constructor of pyramid.view.view_config. It can be
used in the same places, and behaves in largely the same way, except
it always registers a not found exception view instead of a ‘normal’
view.
On one hand, it seems like I should be able to specify 'renderer' as a parameter since it's supported in pryamid.view.view_config. On the other hand, it sounds like it's always loading the [not found exception view][3], regarless of the 'renderer' option.
Really, my ultimate question (and goal) is, how do I display/render my template whenever a page is not found?
The renderer-view relationship is always the same in Pyramid. If you return a Response object, then your declared renderer is bypassed. This allows you to do things like if submitted: return HTTPFound(location=...) else: return {}. If you'd like to affect the response object and still use your renderer, then return the required dict and mutate request.response, the response object that is used for all renderers.
#notfound_view_config(renderer='templates/notfound.pt')
def notfound(request):
request.response.status = 404
return {}

Categories

Resources