In django, I defined url like that
(r'^checkstring/(?P<string>\w+)/$',views.check_str,name='check str')
But, When i enter string inputs like ibrahim.yilmaz, ibrahi!m or ibrahim#ibrahim.com, it returns http 404.
So how can i write the url which accept everykind of string?
any help will be appreciated.
İbrahim
Django uses regular expressions to match incoming requests. In python a dot (.) matches any character except a newline. See docs for more information and try:
(r'^checkstring/(?P<string>.+)/$',views.check_str,name='check str')
Also keep in mind that this will accept any character (including the forward slash) which may not be desirable for you. Be sure to test to make sure everything works as you would expect.
In Django >= 2.0, you can implement in the following way.
from django.urls import path
urlpatterns = [
...
path('polls/<string>/$','polls.views.detail')
...
]
For Django 2.0
import re_path in urls.py file
like this:from django.urls import re_path
then in the urlpatterns write the following code:
urlpatterns = [ re_path('prefixs/.*', your_ViewClass_name.as_view()), ]
Related
I'm trying to use an escaped url as a re_path variable for an object identifier in my API. The logic to connect the escaped url to an object is there, but I can't figure out why the regex is not matching.
In my head, a GET request with the following url /objects/http%3A%2F%2F0.0.0.0%3A3030%2Fu%2F%3Fid%3Dc789793d-9538-4a27-9dd0-7bb487253da1/foo should be parsed into obj = 'http%3A%2F%2F0.0.0.0%3A3030%2Fu%2F%3Fid%3Dc789793d-9538-4a27-9dd0-7bb487253da1' and field = 'foo' for further processing. Ultimately, returning the object and 200. However I am getting a 404 with a very specific Django error that only proliferates when Django unfruitfully iterates through all the paths available.
<HttpResponseNotFound status_code=404, "text/html">
(Pdb) response.content
b'\n<!doctype html>\n<html lang="en">\n<head>\n <title>Not Found</title>\n</head>\n<body>\n <h1>Not Found</h1><p>The requested resource was not found on this server.</p>\n</body>\n</html>\n'
I know the path exists as when I examine the urlpatterns, the path is present:
(Pdb) pp object_router.get_urls()
[
...
<URLPattern '^(?P<obj>https?[-a-zA-Z0-9%._\+~#=]+)/(?P<field>foo|bar)\/?$' [name='test-detail-foobar']>
]
The url is escaped with urllib.parse.quote(obj.url, safe="")
Regexs tried:
r"https?[-a-zA-Z0-9%._+~#=]+"
r"https?[%23A](www\.)?[-a-zA-Z0-9#:%._\+~#=]{2,256}(\.[a-z]{2,6})?\b([-a-zA-Z0-9#:%_\+.~#?&//=]*)(?=\/foo)" https://regexr.com/6ue7b
r"(https?://(www.)?)?[-a-zA-Z0-9#:%.+~#=]{2,256}(.[a-z]{2,6})?\b([-a-zA-Z0-9#:%+.~#?&//=]*)
Edit:
Based off the Django Path Convertor path regex, I've changed my regex to https?.+ with the compiled version as '(?P<obj>https?.+)/(?P<field>foo|bar)\\/?$'. This is moving in the right direction, however I've further identified some weirdness. Basically it seems that escaping the path variable url (obj) is partially to blame for the mismatch as an unescaped url (without query parameters) will return a differently handled API response. Further more, adding a query parameters/a question mark, once again returns us back to the Django 404.
Consider a simple project like this:
urls.py
from django.contrib import admin
from django.urls import path, re_path
from . import views
urlpatterns = [
re_path(r"https?[-a-zA-Z0-9%._+~#=]+", views.test, name="test"),
path('admin/', admin.site.urls),
]
views.py
from django.http import HttpResponse
def test(request, obj, field):
print(f"The object is {obj}")
print(f"The field is {field}")
return HttpResponse("Test test")
When visiting the following URL: /objects/http%3A%2F%2F0.0.0.0%3A3030%2Fu%2F%3Fid%3Dc789793d-9538-4a27-9dd0-7bb487253da1/foo
You get this error:
(I've outlined the relevant part with red.)
Django automatically decodes the encoded URL and only then applies the regex match. objects/http%3A%2F%2F0.0.0.0%3A3030%2Fu%2F%3Fid%3Dc789793d-9538-4a27-9dd0-7bb487253da1/foo becomes objects/http://0.0.0.0:3030/u/?id=c789793d-9538-4a27-9dd0-7bb487253da1/foo. You will have to write the equivalent regex expression that matches against the decoded URL.
Something like this will work:
urls.py
from django.contrib import admin
from django.urls import path, re_path
from . import views
urlpatterns = [
re_path(r"(?P<obj>https?:\/\/.*\?id=[\d\w-]+)\/(?P<field>foo|bar)", views.test, name="test"),
path('admin/', admin.site.urls),
]
views.py
from django.http import HttpResponse
def test(request, obj, field):
print(f"The object is {obj}")
print(f"The field is {field}")
return HttpResponse("Test test")
Visiting the URL /objects/http%3A%2F%2F0.0.0.0%3A3030%2Fu%2F%3Fid%3Dc789793d-9538-4a27-9dd0-7bb487253da1/foo will print the following to the console:
The object is http://0.0.0.0:3030/u/?id=c789793d-9538-4a27-9dd0-7bb487253da1
The field is foo
If I am understanding your issue properly, it looks like you are attempting to get a regex match and immediately send a request to the resultant url?
If that is the case, you are sending the request to an improperly formatted url. The first regex you posted looks like it works just fine to get the result you are asking for, however it results in a url that is still encoded.
You need to "unquote" the url prior to making the request.
import re
from urllib.parse import unquote
path = '/objects/http%3A%2F%2F0.0.0.0%3A3030%2Fu%2F%3Fid%3Dc789793d-9538-4a27-9dd0-7bb487253da1/foo'
resp = re.search("https?[-a-zA-Z0-9%._+~#=]+", path)
url = resp[0]
print(url)
print(unquote(url))
results in and output of:
http%3A%2F%2F0.0.0.0%3A3030%2Fu%2F%3Fid%3Dc789793d-9538-4a27-9dd0-7bb487253da1
http://0.0.0.0:3030/u/?id=c789793d-9538-4a27-9dd0-7bb487253da1
I just started up with django.
Following this tutorial, I ended up with the following urls.py:
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('polls/', include('polls.urls')),
path('admin/', admin.site.urls),
]
This links to polls.urls.py which has its own router.
The part I don't like is the string literal 'polls.urls' which is, well... a string literal.
I would like to somehow reference the file directly using some of python's power, and have AT LEAST my IDE protect me.
What happens if I want to move that polls.urls.py file, or rename it, or rename polls? Should I trust my IDE to catch a reference from a string literal?
This is almost like doing this monstrosity, and is very hard for me to accept as the best practice.
It just seems odd to me.
Is there a way to use something less prone to errors than string literals in django's routers?
I don't see problems with using string literals as URLconf is loaded prior to starting of server (runserver)
If there is a problem you would get ModuleNotFound error
From source of include() :
if isinstance(urlconf_module, six.string_types):
urlconf_module = import_module(urlconf_module)
You would see good amount of import_module usage through Django framework and string literals.
Your IDE would know if there is unresolved reference (Pycharm does)
So from what I understand or what I know there are two ways of url mapping using the
path' orurl`
for path method you bound to do what you did that is:
from django.urls import path, include
but you are to also import your views.py
For second method your are to:
from django.conf.urls import url
then your are to import your views there as:
from .views import home_page
home_page being a function or class in your views.py
Example of mapping
url(r'^home/$', home_page),
so no need to actually to actually create urls.py if you use this method
I have already checked this error on other stackoverflow threads but don't find any error on my code. Perhaps I'm tired but it seems ok to me.
website.urls.py:
from django.conf.urls import patterns, include, url
#from django.contrib import admin
urlpatterns = patterns('',
# Register and Login
url(r'^inscription\.html$', 'membres.views.register'),
# List of users
url(r'^membres', include('membres.urls')),
)
membres.urls.py:
from django.conf.urls import patterns, url
urlpatterns = patterns('membres.views',
url(r'^/(?P<slug>\d+)\.html$', 'view_user_public')
)
Of course I get :
Using the URLconf defined in website.urls, Django tried these URL patterns, in this order:
^inscription\.html$
^membres ^/(?P<slug>\d+)\.html$
The current URL, membres/nicolas.html, didn't match any of these.
The inscription.html works properly. In the membres.urls.py file, if I change r'^/(?P<slug>\d+)\.html$ to r'^\.html$, the url membres.html works properly and loads the view...
What's wrong with r'^/(?P<slug>\d+)\.html$ ?
Thanks a lot
\d+ would match digits only. nicolas is not composed of digits.
\w+ is what you're looking for.
More generally, [\w-]+ for slugs which typically contain hyphens.
I have what I think is a pretty simple URL configuration for a public API I'm building in django:
# public API, in urls.py
(r'^api/', include('api.urls'))
# in api/urls.py
api_key_patterns = patterns('api.geoprocessing',
url(r'^land-use/', 'landUse', name='geoprocessing_land_use'))
urlpatterns = patterns('',
url(r'^(?P<api_key>(.+))/', include(api_key_patterns)))
However, when I make a request to /api/123/land-use/ Django's URL resolver cannot find a match. When I debug the urls it has tried, it resolves the above to this:
^api/ (?P<api_key>(.+))/ land-use/ [name='geoprocessing_land_use']
Notice the spaces between (?P<api_key>(.+)) and land-use. Why are these spaces inserted for each include, and how can I get a match?
Update
If I hard-code a url for ^api/(?P<api_key>(.+))/land-use/ I am able to get a match.
Also, if I add a character after the trailing / the URL match also works:
api_key_patterns = patterns('api.geoprocessing', url(r'^and-use/$', 'landUse',name='geoprocessing_land_use'))
urlpatterns = patterns('', url(r'^(?P<api_key>(.+))/l', include(api_key_patterns)))
Try:
urlpatterns = patterns('api.geoprocessing',
url(r'^land-use/(?P<api_key>(.+))/$', 'landUse',
name='geoprocessing_land_use'))
)
I'm not sure what you're trying to accomplish by including a pattern when it doesn't seem like you need to be doing that.
Looks like using a (.+) group within my regular expression was forcing the django URL resolver to look for a character that wasn't there. This always parses when there are characters following the trailing slash, but when this group sits at the end of the url segment, a space is tagged at the end.
I resolved this by exchanging the (.+) group with a simple word matcher \w+:
(r'^api/(?P<api_key>\w+)/', include('api.api')),
the usl :
(r'^account/', include('account.urls')),
(r'^account/', include('django_authopenid.urls')),
i want to use these url , and i dont want to mix it by my hand one by one , it is not very easy ,
has a method to do this in django .
thanks
Your own code can work properly in many cases, but if not you can do
this:
Create your own urls.py file:
from account.urls import urlpatterns as accounts_urlpatterns
from django_authopenid.urls import urlpatterns as authopenid_urlpatterns
urlpatterns = patterns("")
urlpatterns += accounts_urlpatterns
urlpatterns += authopenid_urlpatterns
What you do will work, with the caveat that any pattern that would match an entry in both would be found by the first one you list.
For instance, the url /account/openid/foo/ might match a pattern in django_authopenid.urls that is r'^openid/(.*)/$', but that would never hit if there was a match in account.urls that also matched, such as r'^(.*)/foo/$'.