Route Flask : Problem of space and accent in a route with variable - flask

I created an application with Flask.
Locally, everything works.
But now that I have sent to the server, I have a routing problem.
The url that causes the problem is built like this:
#app.route('/analyze/<string:keyword>')
The problem is that the keyword variable can contain accents (éèàç, etc ...) and spaces (example : sol stratifié)
The problem is that instead of laminate floor, I have sol%20stratifi%c3%a9 which appears on the screen, but also when I call the database.
I tried:
encode and decode utf- 8 on the keyword variable : it doesn't work
import codecs : it doesn't work
test to use the function : Flask URL route encoding problems
try to add .encode('utf-8') directly in the url route
would you have a solution ?

sol%20stratifi%c3%a9 is a percent-encoded string (URL quoted or %xx escaped in Python terminology).
The urllib.parse module defines functions that fall into two broad categories: URL parsing and URL quoting.
from urllib.parse import unquote
print( unquote( 'sol%20stratifi%c3%a9'))
sol stratifié

Related

Parse &-character in GET query using Django and Vue

We are using axios to pass GET request to our django instance, that splits it into search terms and runs the search. This has been working fine until we ran into an edge case. We use urlencode to ensure that strings do not have empty spaces or others
So generalize issue, we have TextField called "name" and we want to search for term "A & B Company". However, issue is that when the request reaches django.
What we expected was that name=A%20&%20B%20Company&field=value would be parsed as name='A & B Company' and field='value'.
Instead, it is parsed as name='A ' 'B Company' and field='value'. The & symbol is incorrectly treated as separator, despite being encoded.
Is there a way to indicate django GET parameter that certain & symbols are part of the value, instead of separators for fields?
You can use the lib urllib
class ModelExample(models.Model):
name = models.TextField()
# in view...
from urllib.parse import parse_qs
instance = ModelExample(name="name=A%20&%20B%20Company&field=value")
dict_qs = parse_qs(instance.name)
dict_qs contains a dict with decoded querystring
You can find more informations about urllib.parse here: https://docs.python.org/3/library/urllib.parse.html

Prevent URL encoding that is removing equals signs from URL

Working on a Django/React app. I have some verification emails links that look like the following:
https://test.example.com/auth/security_questions/f=ru&i=101083&k=7014c315f3056243534741610545c8067d64d747a981de22fe75b78a03d16c92
In dev env this works fine, but now that I am getting it ready for production, it isn't working. When I click on it, it converts it to:
https://test.example.com/auth/security_questions/f%3Dru&i%3D101083&k%3D7014c315f3056243534741610545c8067d64d747a981de22fe75b78a03d16c92/
This prevents react-router-dom from matching the correct URL, so a portion of the web application does not load properly.
The link is constructed using the following.
link = '%s/auth/security_questions/f=%s&i=%s&k=%s' % \
('https://test.example.com', 'ru', user.id, user.key)
Also, here is the url() that is catching the route:
url(r'^(?:.*)/$', TemplateView.as_view(template_name='index.html')),
These variables are supposed to be query parameters in a GET request. When you construct the link, you'll need to have a question mark in there somewhere separating the URL from the query string:
https://test.example.com/auth/security_questions/?f=ru&i=101083&k=7014c315...
^
|___ here
The conversion of = to url-encoded %3D etc is correct, and equivalent. Sometimes variables are part of the URL directly, but webapps don't use &-separated key/value pairs in that case.

Prevent escaping slashes in url helpers (specifically when called using .send() to url_helpers)

Perhaps the title of this question is cryptic, but the problem is real, I've just upgraded an application from Rails 3 to 4 and encountered the following issue (on both Ruby 2.0 and 2.1):
I have a method which calls several url helpers in a loop, using send(), like this:
class Sitemap
include Rails.application.routes.url_helpers
#...
# regions = [:city, :county, :zip]
regions.each do |region|
url_params = ... # [name, additional_id]
send("#{region}_url", url_params)
end
In Rails 3 the above resulted in urls like http://example.com/cities/atlanta/2
In Rails 4 I get http://example.com/cities/atlanta%2f2
slash gets CGI escaped, I don't want this. I use it in generating sitemap XML for my site and it seems to work even if the forward slash is escaped, but it looks ugly and I don't know if it will work correctly for all bots or clients.
UPDATE: after some debugging I've found out that the CGI escaping occurs somewhere in ActionDispatch::Journey::Visitors::Formatter
Router::Utils.escape_segment() # method call somewhere in
ActionDispatch::Journey::Visitors::Formatter # during
Visitors::Formatter.new(path_options).accept(path.spec) # in
#set.formatter.generate(:path_info, named_route, options, recall, PARAMETERIZE) # in a call to
ActionDispatch::Routing::RouteSet::Generator#generate
I was able to fix the issue with escaping slashes when generating the URL, here's the change:
# from:
send(region_url, url_params)
# to:
send(region_url, { id: url_params[0], market_id: url_params[1]})
# sometimes url_params is a one element array
The key is to provide a hash of parameters with explicitly assigned keys and values.
I use send to dynamically call method (xxx_url) from url_helpers module which is included in my model. url_params array looks like ['some-slug', 12]

django url pattern for %20

In Django what is the url pattern I need to use to handle urlencode characters such as %20
I am using (?P<name>[\w]+) but this only handles alphanumeric characters so % is causing an error
I was able to make it work using the configuration given below. Check if it will suit your needs.
(?P<name>[\w|\W]+)
If you only want to allow space:
(?P<name>[\w\ ]+)
The best way to do that and allow others chars is using '\s' that is any spaces, tabs and new lines
(?P<name>[\w\s]+)
I am using Django 2.2.
It handles the %20 (which means space) in url using Path converter: str
You simply need to use:
<name> or <str:name>
For example, following example loads view "some_view" defined in view.py
#urls.py
from django.urls import path
from . import views
urlpatterns = [
path("<name>",views.some_view),
....
]
The following function renders "some.html" after processing. In this example sending the received name to "some.html".
#view.py
def some_view(request, name):
# process here
context = { "name" : name }
return render(request,"some.html",context)

Django: # in url as a character?

I've made a Django application that uses tags. When i use tag 'c#' and try to redirect to mysiteaddress/tags/c# on server it redirects to ../tags/c and shows me stuff connected to 'c' tag, but when I do the same on my local development machine it redirects me to c%23 and works correctly. What should I change to make it work on production server?
Without more code I can't be too specific, but '#' corresponds to the character escape sequence %23 and something in your code may need to explicitly escape 'c#' before putting it in the url.
Here is a django-snippet that uses url-quoting:
http://www.djangosnippets.org/snippets/1159/
The solution to your problem might look like this:
from django.utils.http import urlquote
...
tag = urlquote(tag)
tag_url = base + "tags/" + tag
...