Persian text in url Django

Viewed 938

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'
3 Answers

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

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 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 :)

Related