django url pattern for %20 - django

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)

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

How to pass # in url as a parameter in django 2

I am trying to pass a code "Req-2019#000001" Django URL. I want to pass this code as well as normal string and number also in URL as arguments.
path('generateBomForSingleProduct/<requisition_no>/' , views.generateBomForSingleProduct, name='generateBomForSingleProduct'),
Its work properly but the problem is its add extra / before #
My URL is now this
http://127.0.0.1:8000/production/generateBomForSingleProduct/Req-2019/#000001
But I want to like this
http://127.0.0.1:8000/production/generateBomForSingleProduct/Req-2019#000001
Not an extra "/" before my "#"
The portion of the URL which follows the # symbol is not normally sent to the server in the request for the page. So, it's not possible to have a URL as /production/generateBomForSingleProduct/Req-2019#000001
Workaround
Just modify the url as /production/generateBomForSingleProduct/Req-2019/000001, so you need to modify the view also
# views.py
def generateBomForSingleProduct(request, part_1, part_2):
unique_id = "{}#{}".format(part_1, part_2)
# use the "unique_id"
...
#urls.py
urlpatterns = [
...,
path('foo/<part_1>/<part_2>/', generateBomForSingleProduct, name="some-name"),
...
]
Using 'get' would be the proper way to do this. # is for html fragments, which are not sent to the server. Why can't it just be
/production/generateBomForSingleProduct/Req-2019?code=000001 and then you handle everything in the view that way?
Part after # is called fragment identifier, which is used by browsers and never sent to server.
In http://127.0.0.1:8000/production/generateBomForSingleProduct/Req-2019/#000001 url 000001 is never sent to server. Hence using important part of url after # is useless. Better to pass 000001 as query parameters or separate argument.

Django URLresolver, optional value

In my urls.py file, I currently have the following resolver :
url(r'$', 'methodology_home')
url(r'^(?P<methodology_type\w+)/$', 'methodology_home')
I'd like the merge the two by saying that methodology_type is optional (and by specifying an argument with a default value in my view).
Is it feasible by simply adding a ? in the regexp ? I thought so at first but I was unable to make it work.
Does someone has an idea ?
Thanks.
You can write a regex to catch an optional url paramater
url(r'^(?:(?P<methodology_type>\w+)/?)?$', 'methodology_home')
One issue with this approach, though, is that your view will get None if no parameter is given. That's because the regex will in fact match and the value of the group is None:
import re
pattern = re.compile(r'^(?:(?P<methodology_type>\w+)/?)?$')
pattern.match('foo').groupdict()
>>> {'methodology_type': 'foo'}
pattern.match('').groupdict()
>>> {'methodology_type': None}
So you either handle it in your view code:
def my_view(request, methodology_type):
methodology_type = methodology_type or 'default'
...
or you stick with the two separated rules you already have.

What's the correct regex for a required string and optional string in Django?

So in my Django URLS I want to be able to support:
mysite.com/section
mysite.com/section/
mysite.com/section/sectionAlphaNum
mysite.com/section/sectionAlphaNum/
I currently have as the URL pattern:
(r'^section/(?P<id>\s?)?', section)
Which should make section/ required and anything after optional, but it never seems to catch whatever sectionAlphaNum I enter in. In my views.py file I have
def section(request,id):
if id == '':
# Do something with id
else:
# Do default action
But it never seems to get into the top if branch where it does something with the id
Can you try the following syntax: (r'^section/(?P<id>\w+)/$', section)?
In regular expressions the ^ and $ represent the start and end of the string respectively.
Hence the URL to display /section/ would be:
(r'^section/$', section_view)
while the URL to display a specific section /section/section-id/ would be :
(r'^section/(?P<section_id>\w+)$', section_detail_view)
Ideally you have separate views in your views.py:
def section_view(request):
# show page about the various sections
def section_detail_view(request, section_id):
# show page about specific section by section_id
urls.py:
...
(r'^section/$', section),
(r'^section/(?P<id>\w+)/$', section),
...
views.py:
def section(request, id=None):
if id is None:
...
else:
...
To append just slash (from /section to /section/) enable CommonMiddleware in Your settings' MIDDLEWARE_CLASSES.
(r'^section(?:/(?P<id>\w+))?/$', section)
Notice the last ? to make the whole (?:/(?P<id>\w+)) optional.
Other answers are missing the ? or they don't make one of the slashes (/) optional like I do with the first one in (?:/( ...
r'^section/(?:(?P<id>\w+)/)?$' # same result, last '/' optional.
And make the parameter optional in the function as well:
def section(request, id=None):
# ...

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