2

I'm building URLs that look like this, routing with Flask:

http://hostname/nris/resource/00001234 http://hostname/nris/resource/99000025

The last segment is an 8 digit integer that will match a string in my database. The leading zeros, if any, are significant.

I've implemented a custom regex converter, based on Does Flask support regular expressions in its URL routing?. That works fine as long as the numeric field starts with a non-zero. Here's my routing code (loaded within /nris/):

@app.route('/numish/<regex("[0-9]{8}"):resourcenum>/')
def numish(resourcenum):
    return "resourcenum: %s" % (resourcenum)
@app.route('/resource/<regex("[0-9]{8}"):resourcenum>/')
def resource_page(resourcenum):
    return render_template('singlemap.html', propnris=resourcenum)

When I visit http://hostname/nris/numish/00000004, I see

resourcenum: 00000004

But when I display it in my template, all that's shown on the console is 4, and the database query performed in addSingleSiteLayer() gets 4, not 00000004. Here's the Jinja code I'm using to generate JavaScript:

{% extends "maptemplate.html" %}
{% block mapcustom %}
console.log( "hello" );
console.log( {{propnris}} );
addSingleSiteLayer(map, {{propnris}} );
{% endblock %}

I could simply reformat the incoming value into an 8 character string with leading zeros. But I'd rather pass the parameter down so that it doesn't get truncated in the first place. Is there a clean way to do this?

Community
  • 1
  • 1
Hal Mueller
  • 7,019
  • 2
  • 24
  • 42

2 Answers2

3

You are passing your values to JavaScript, and it is ignoring the leading zeros on the integer literal you gave it. This is hardly Python or Flask's fault.

Make it a string literal by wrapping the value in quotes:

{% extends "maptemplate.html" %}
{% block mapcustom %}
console.log( "hello" );
console.log( "{{propnris}}" );
addSingleSiteLayer(map, "{{propnris}}" );
{% endblock %}

or better still, format it as JSON to have any quoting issues handled for you:

{% extends "maptemplate.html" %}
{% block mapcustom %}
console.log( "hello" );
console.log( {{propnris|tojson|safe}} );
addSingleSiteLayer(map, {{propnris|tojson|safe}} );
{% endblock %}

as Flask's tojson filter produces valid JavaScript-compatible JSON output this can be interpreted directly as JavaScript literals, and a Python string is rendered properly quoted.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
2

BTW, for the original problem of the url route in Flask you can now specify parameter with a fixed number of digits.

e.g.

@app.route('/numish/<int(fixed_digits=8):resourcenum>/')

The when you use url_for() in your code, the url will be constructed with the correct number of digits.

Further details on the available routing parameters here: http://werkzeug.pocoo.org/docs/0.14/routing/

cmuk
  • 473
  • 5
  • 9