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')),
Related
I'm trying to generated nested url paths. So far I could only generate 1 level urls. When I try second level urls it doesn't get called anymore, it still only shows the first level url although the address bar on the browser does direct to the second level url. Is this possible or do I need to create a new app?
urls.py
from django.conf.urls import url, include
from django.views.generic import ListView, DetailView, TemplateView
from dashboard.models import IPARate,PCPRate
from dashboard import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^medicare/', ListView.as_view(queryset=IPARate.objects.all().order_by("id"), template_name='dashboard/medicare.html')),
url(r'^medicare/medicarepcp/$', ListView.as_view(queryset=PCPRate.objects.all().order_by("id"), template_name='dashboard/medicarepcp.html')),
url(r'^medicare/', views.medicaid, name='medicare'),
url(r'^medicare/medicarepcp/$', views.medicarepcp, name='medicarepcp'),
]
You need to add a dollar (end of line character) to the r'^medicare/ regex, so that it matches /medicare/ but not other URLs like medicare/medicarepcp/.
url(r'^medicare/$', ListView.as_view(queryset=IPARate.objects.all().order_by("id"), template_name='dashboard/medicare.html')),
url(r'^medicare/medicarepcp/$', ListView.as_view(queryset=PCPRate.objects.all().order_by("id"), template_name='dashboard/medicarepcp.html')),
The third and the fourth regexes are the same as the first and the second respectively. Django will always match the first two URL patterns, so you need to change the third and fourth URL patterns to something else.
The order of URLs is important, as Django will react to the first URL pattern that matches the request. A good habit is to put all of your "sub" URLs first, then the top level of that section last, so it works as a fall-back if no others match (i.e. put your '^medicare/$' last).
This is a silly problem. I just created a project and have been trying to figure out this problem.
from django.conf.urls import url
from django.views.generic import TemplateView
urlpatterns = [
url(r'^$', TemplateView.as_view(template_name="index.html")),
url(r'^about$', TemplateView.as_view(template_name="about.html")),
url(r'^contact$', TemplateView.as_view(template_name="contact.html"), name="contact"),
url(r'^test$', TemplateView.as_view(template_name="test_start"), name="test_start"),
url(r'^test/sample$', TemplateView.as_view(template_name="test_start"), name="test_start"),
]
is included into
from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^', include('frontend.urls'))
]
When I go to localhost:8000/about, I get redirected to localhost:8000/about/ and there I get 404 Not Found.
UPDATE: I added more URLs into my URLconf.
UPDATE 2: I meant to not include trailing slashes. My apologies.
UPDATE 3: I opened the same URL in Firefox and the URL works like I intend. Could this be a problem with redirection and browser cache?
Did you enable the append_slash setting ?
https://docs.djangoproject.com/en/dev/ref/settings/#append-slash
using this may help to make it more explicit and is recommended throughout the django tutorials
url(r'^about/$', TemplateView.as_view(template_name="about.html")),
EDIT:
Deactivate the APPEND_SLASH settings (False) and use
url(r'^about$', TemplateView.as_view(template_name="about.html")),
First, I found out that Chrome automatically adds trailing slash at the end of the URL
Trailing URL Slashes in Django
So if you don't have a trailing slash on your URLS, a 404 redirect will show if you're using Chrome, but not if, say, Firefox.
Then from the comment of knbk from here,
How Django adds trailing slash
I made sure I had the CommonMiddleware class in setting.py and added 'APPEND_SLASH = False'
Then, cleared Chrome's cache, and problem solved!
You can just remove the $ from your regex, this indicates the end of line
url(r'^about', TemplateView.as_view(template_name="about.html")),
You could also just include a slash to your regex, since Django has a APPEND_SLASH setting which will issue a redirect
url(r'^about/$', TemplateView.as_view(template_name="about.html")),
if the request URL does not match any of the patterns in the URLconf and it doesn’t end in a slash, an HTTP redirect is issued to the same URL with a slash appended.
Change your url pattern for "about" to:
url(r'^about/?$', TemplateView.as_view(template_name="about.html")),
Without the /?, the regex ^about$ matches a string containing exactly the word "about".
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 found an interesting thing I don't know how to solve:
urlpatterns = patterns('',
url(r'^$', 'my_app1.views.index', name='index'),
url(r'^path1/path2/', 'my_app1.api.method1')
// or url(r'^path1/path2', 'my_app1.api.method1')
)
I don't want the urls to contain "/" at the end.
If I go to http://localhost:8000/path1/path2 it redirects me to http://localhost:8000/path1/path2/ with the "/" at the end. Whatever I do to get rid of the "/" at the end of the url, I fail at. It seems there's no way to do so, unlike in Rails. Is it true?
You can control it using settings.APPEND_SLASH.
By default, it's True. Change the value to False in the project settings file.
APPEND_SLASH = False
But if you set it, accessing the page /path/path2 will result 404 error. You need to change the url pattern:
url(r'^path1/path2/?', 'my_app1.api.method1') # To match url with/without trailing /
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()), ]