django unicode url - django

on deployment (Django + Dreamhost + passenger_wsgi)
in my urls.py:
url(ur'^(?P<url>.+)/$', 'alp.news.views.blog_dispatcher', name='blog_dispatcher'),
the link:
domain.name/%D0%98%D0%BD%D1%84%D0%B02/
leads to (looks like redirection):
domain.name/%25d0%2598%25d0%25bd%25d1%2584%25d0%25b02/
so, the "url" variable in my view = "%25d0%2598%25d0%25bd%25d1%2584%25d0%25b02"
locally (or using dev server)
When I use runserver command, even on deployment, it works well.
Ofcourse I could use urllib and unquote the url in my view, but the string in url still transforming '%' -> '%25'.
Have no idea, where does the magic begin: in passenger or wsgi app
May be someone could clear up ...

the magic was in dreamhost's 301 redirection, which double-quoted the path

Related

Persian text in url Django

I have some links that include Persian texts, such as:
http://sample.com/fields/طب%20نظامی
And in the view function I want to access to Persian part, so:
url = request.path_info
key = re.findall('/fields/(.+)', url)[0]
But I get the following error:
IndexError at /fields/
list index out of range
Actually, the problem is with the index zero because it can not see anything there! It should be noted that it is a Django project on IIS Server and I have successfully tested it with other servers and the local server. I think it has some thing related to IIS. Moreover I have tried to slugify the url without success. I can encode urls successfully, but I think it is not the actual answer to this question.
Based on the comments:
I checked the request.path too and the same problem. It contains:
/fields/
I implemented a sample django project in local server and here is my views:
def test(request):
t = request.path
return HttpResponse(t)
The results:
http://127.0.0.1:8000/تست/
/تست/
Without any problem.
Based on the #sytech comment, I have created a middlware.py in my app directory:
from django.core.handlers.wsgi import WSGIHandler
class SimpleMiddleware(WSGIHandler):
def __call__(self, environ, start_response):
print(environ['UNENCODED_URL'])
return super().__call__(environ, start_response)
and in settings.py:
MIDDLEWARE = [
...
'apps.middleware.SimpleMiddleware',
]
But I am getting the following error:
__call__() missing 1 required positional argument: 'start_response'
Assuming you don't have another problem in your rewrite configuration, on IIS, depending on your rewrite configuration, you may need to access this through the UNENCODED_URL variable which will contain the unencoded value.
This can be demonstrated in a simple WSGI middleware:
from django.core.handlers.wsgi import WSGIHandler
class MyHandler(WSGIHandler):
def __call__(self, environ, start_response):
print(environ['UNENCODED_URL'])
return super().__call__(environ, start_response)
You would see the unencoded URL and the path part that's in Persian would be passed %D8%B7%D8%A8%2520%D9%86%D8%B8%D8%A7%D9%85%DB%8C. Which you can then decode with urllib.parse.unquote
urllib.parse.unquote('%D8%B7%D8%A8%2520%D9%86%D8%B8%D8%A7%D9%85%DB%8C')
# طب%20نظامی
If you wanted, you could use a middleware to set this as an attribute on the request object or even override the request.path_info.
You must be using URL rewrite v7.1.1980 or higher for this to work.
You could also use the UNENCODED_URL directly in the rewrite rule, but that may result in headaches with routing.
I can encode urls successfully, but I think it is not the actual answer to this question.
Yeah, that is another option, but may result in other issues like this: IIS10 URL Rewrite 2.1 double encoding issue
You can do this by using python split() method
url = "http://sample.com/fields/طب%20نظامی"
url_key = url.split(sep="/", maxsplit=4)
url_key[-1]
output : 'طب%20نظامی'
in this url is splited by / which occurs 4 time in string so it will return a list like this
['http:', '', 'sample.com', 'fields', 'طب%20نظامی']
then extract result like this url_key[-1] from url_key
you can Split the URL by :
string = http://sample.com/fields/طب%20نظامی
last_part = string. Split("/")[-1]
print(last_part)
output :< طب%20نظامی >
slugify(last_part)
or
slugify(last_part, allow_unicode=True)
I guess This Will Help You :)

Django missed slash in url

I created a url like 'api/personal/'. Everything went right when I did local test using './manage.py runserver'. But when I used factoryboy to create a client and try to get the detail by 'self.user_client.get('api/personal/')', the response showed 404 NOTFOUND because the url had changed to apipersonal/. Does anyone know why did it happen?
Use named urls for avoiding this kind of confusions. Define the url like this:
path('api/personal/', your_view, name='api_personal') # added keyword argument name
and use it in the tests with reverse like this:
self.client.get(reverse('api_personal'))

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.

Right way to handle HttpResponseRedirect

I have a Django app I'm trying to deploy. The Apache setting is configured in the way that i access my wsgi app by the following URL:
sitename.com/~amartino
Meaning I have only a wsgi.py file in my public_html directory.
I access my Django site via URL:
sitename.com/~amartino/expofit
For that's the way its been set in urls.py.
urlpatterns = patterns('',
('/param_select/$',session_check(param_select)),
('registration/$',registration),
('result_show/(\d+)',session_check(result_show)),
('^expofit/$',media_clean(start)),
('result_pick/$',session_check(result_pick)),
('mail_report/$',session_check(mail_report)),
('notification/$',session_check(notification)),
However, the problem I'm getting (which didn't show up in development :) ) is that I'm using a hardcoded HttpResponseRedirect in views.py.
...
#If all fields are valid
return HttpResponseRedirect('/expofit/param_select/')
#else reload page
...
Since the production environment doesn't place my site in the root of the URL, i'm having errors now because the upper HttpResponseRedirect translates to
sitename.com/expofit/param_select/
which isn't recognized by Apache.
I suppose I could remove the slash and have:
return HttpResponseRedirect('expofit/param_select/')
which would result in:
sitename.com/~amartino/expofit/registration/expofit/param_select/
but that doesn't seem the right way to do it for I would end up with a huge URL in no time.
Where is the design/configuration flaw here?
"the problem I'm getting that I'm using a hardcoded HttpResponseRedirect"
Well, don't do that then. That's why Django provides the reverse function, which takes your url name and calculates the proper absolute URL.

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
...