Django - Url dispatch No match from application - regex

I have a simple url that doesn't match into one of my applications (plaq)
main url.py:
urlpatterns = patterns('',
#...
url(r'^content/', include('content.urls')),
url(r'^$', include('content.urls')),
url(r'^plaq/', include('plaq.urls')),
#...
)
plaq url.py:
urlpatterns = patterns('',
(r'^$', pres),
(r'pres^$', pres),
(r'about^$', about),
(r'privacy^$', privacy),
)
Trying to access to my_host/plaq/pres gives me
Using the URLconf defined in my_project.urls, Django tried these URL patterns, in this order:
...
12. ^content/
13. ^plaq/ ^$
14. ^plaq/ pres^$
15. ^plaq/ about^$
16. ^plaq/ privacy^$
...
The current URL, plaq/pres/, didn't match any of these.
While my_host/plaq displays the good pres view
Why can't I access to my_host/plaq/pres ?

Firstly, you need to learn a bit about regexes: ^ means beginning of string, but for some reason you have it at the end.
Secondly, your URLs end in slashes, so your urlconfs must too.
urlpatterns = patterns('',
(r'^$', pres),
(r'^pres/$', pres),
(r'^about/$', about),
(r'^privacy/$', privacy),
)

carets (^) match the beginning of a string. i think you want e.g. (r'^pres$', pres), (caret moved to front)

Related

How can I use a catch all route using `path` or `re_path` so that Django passes all unmatched requests to my index view?

My url patterns look like this:
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('api.urls')),
re_path('.*', IndexView.as_view()),
]
This works but it matches all URLs, including those prefixed with admin and api. I want those URLs to still match, and for any unmatched URLs to render IndexView.
Before 2.0 I used this regex for this purpose. I tried using it in re_path but that didn't work, which is what led me to trying the above.
url(r'^(?P<path>.*)/$', HtmlView.as_view())
Use case is a SPA where I handle 404s client side.
Many thanks in advance.
You can use two entries (one for '/', another one for anything else), but using path for both of them, which should be (slightly) more efficient:
urlpatterns = [
path('', IndexView.as_view(), {'resource': ''}),
path('<path:resource>', IndexView.as_view())
]
In this case, I'm using <path:resource> because path catches all resource names, inluding that with / in them. But it does not capture the main index resource, /. That's why the first entry. The dictionary as last argument for it is because we need to provide a resource parameter if we want to use the same view than in the second entry.
That view, of course, should have 'resource' as a paremeter:
def as_view(request, resource):
...
So as I said in the question description, trying the regex I was using before Django 2.0 in re_path did not work. It would basically match for all requests except / (i.e., index path). I fixed this by using both that regex and a second path matching / specifically. Here's the code:
urlpatterns = [
re_path(r'^(?P<path>.*)/$', IndexView.as_view()),
path('', IndexView.as_view()),
]
With these changes my other routes would match and these two routes would account for all other urls.
One Idea to go about this is let the django catch 404.
url.py
from django.conf.urls import handler404
handler404 = 'app_name.views.bad_request'
and in your views.py
views.py
def bad_request(request):
return redirect(reverse('home'))
You can always do some regex thingy to catch unmatched urls. but hey this gets the job done. :)

Django urls space gets added after main url

I get this error message
Using the URLconf defined in esarcrm.urls, Django tried these URL patterns, in this order:
1. ^person/ duplicate_check/(?P<entity>)/(?P<full_name>)/?$
2. ^admin/
3. ^api/v1/
4. ^api/v1/authenticate/$ [name='api_authenticate']
5. ^static\/(?P<path>.*)$
6. ^media\/(?P<path>.*)$
The current path, person/duplicate_check/candidate/tom, didn't match any of these.
Please not the space here 1. ^person/[SPACE]duplicate_check
my project/urls.py
urlpatterns = [
url(r'^person/', include('person.urls')),
url(r'^admin/', admin.site.urls),
url(r'^api/v1/', include(router.urls)),
url(r'^api/v1/authenticate/$', crm_views.ApiAuthenticateView.as_view(), name='api_authenticate'),
]
my app.urls
urlpatterns = [
url(r'duplicate_check/(?P<entity>)/(?P<full_name>)/?$', views.check_if_exist),
]
my app.views
#api_view(['GET'])
def check_if_exist(request, entity, first_name):
if entity == 'candidate':
candidates = person_models.Candidate.objects.filter(first_name=first_name)
serializer = person_serializers.CandidateMiniSerializer(candidates, many=True)
return Response(serializer.data)
What exactly am I missing?
There is no space, that's just how Django prints the URLs.
The problem has nothing to do with spaces, but with your URL. "duplicate_check" is included under person/, but you are trying to access p_check/....
Edit There are actually bigger problems with your URL pattern. You haven't actually given the capturing groups anything to capture. You need some kind of pattern inside the parentheses. Something like:
r'^duplicate_check/(?P<entity>\w+)/(?P<full_name>\w+)/?$'
which will capture all alphanumeric characters for entity and full_name.

understading django.shortcuts.reverse, part 2

In Understanding django.shortcuts.redirect I started a thread about reverse and redirect_to.
I still have some problems understanding how reverse works when the first parameter is a string. I read https://docs.djangoproject.com/en/1.4/topics/http/shortcuts/#django.shortcuts.redirect many times and the corresponding part with reverse. But I am still getting a NoReverseMatch exception.
In my ROOT_URLCONF I have
urlpatterns = patterns('',
url(r'^$', redirect_to, {'url': '/monitor/'}),
url(r'^monitor/', include('monitor.urls')),
)
In monitor.urls I have
urlpatterns = patterns('monitor.views',
(r'^$', 'index'),
(r'^list', 'listall'),
)
and in monitor.urls I've defined code for both functions, index and listall. In listall I added the following lines:
def listall(request):
<more code goes here>
print "reversing 1 index: %s " % reverse(index)
print "reversing 2 index: %s " % reverse('index')
render_to_response("monitor/list.htmld", params)
If I visit localhost:3000/monitor/list then I can see
reversing 1 index: /monitor/
and nothing else, the second reverse raises an exception. Why? What am I missing?
I tracked it down to djangos code django.core.urlresolvers.callable and django.core.urlresolvers.get_mod_func. get_mod_func seems to expect something like "a.b", thats why in callable the very first line returned "index" for func_name but an empty string for mod_name. I changed my second line to
print "reversing 2 index: %s " % reverse('monitor.views.index')
and it worked as intended. So, why do I need to call reverse with the full module and function name (when I use strings) and the documentation doesn't? What am I missing?
Thanks
I'm not sure what part of the documentation you're hung up on, but reverse's first parameter is some identifying method of getting to a view: it can be either a urlpattern name, a full dotted path to the view, or the view itself
So, based on your example, the first method is out because you didn't define a name for your urlpattern. Your first try, reverse(index) worked because you literally passed it the view. Your second try, reverse('index'), doesn't work because it need the full import context, i.e. 'monitor.views.index'. The difference between the two is that when it's a string, Django must interpret that string to create an import for the view -- and 'index' is not enough information to determine the import path.
However, it's far, far better to just name your views if you intend on reversing them, and you should also namespace your included urlpatterns so two different apps don't end up conflicting. So in the project-level urls.py:
urlpatterns = patterns('',
url(r'^$', redirect_to, {'url': '/monitor/'}),
url(r'^monitor/', include('monitor.urls', namespace='monitor', app_name='monitor')),
)
Then, in monitor/urls.py:
urlpatterns = patterns('monitor.views',
(r'^$', 'index', name='index'),
(r'^list', 'listall', name='listall'),
)
Then, reversing is as simple as reverse('monitor:index').
you should be doing something like
reverse('monitor:index')
In ROOT_URLCONF I have
urlpatterns = patterns('',
(r'^$', redirect_to, {'url': '/monitor/'}),
(r'^monitor/', include('monitor.urls'),namespace='monitor'),
)
and in monitor.url.py:
urlpatterns = patterns('monitor.views',
url(r'^$', 'index',name='index'),
)
for more details look at https://docs.djangoproject.com/en/1.4/topics/http/urls/#django.core.urlresolvers.reverse

Django url regexp not working

I'm trying to get my head around regexp in Django urls. I'm currently developing locally and I want to be able to direct a request such as http://localhost:8000/options/items/item-string-1121/ to the 'details' view in my app called 'options', passing in the final number part of the request string (1121) as a parameter 'id' to the view function.
The signature for details in options/views.py is as follows, taking id=1 as default:
def details(request, id=1):
...
I have the following in my root urls.py:
...
urlpatterns += patterns('',
url(r'^options/, include(options.urls')),
)
and in options/urls.py:
urlpatterns = patterns('options.views',
url(r'^items/(.+)(P<id>\d+)/$', 'details'),
...
)
Now when I try to request the above URL the dev server says it tried to match against the pattern ^options/ ^items/(.+)(P<id>\d+)/$ but it doesn't match.
Can anyone see the problem?
You need a non-greedy quantifier on the (.+), so r'^items/(.+?)(P\d+)/$'. Otherwise that first glob happily eats until the end of the string, preventing the ID from ever matching.
You are missing quotes.
urlpatterns += patterns('',
url(r'^options/, include(options.urls')),
)
Should be
urlpatterns += patterns('',
url(r'^options/', include('options.urls')),
)
I'm not too sure of your expression, might try this:
urlpatterns = patterns('options.views',
url(r'^items/(?<=-)(?P<id>\d+)/$', 'details'),
...
)

Error in django url.py?

I am new in django. I try to practice and run the wiki application (i found tutorial at http://showmedo.com/videotutorials/video?name=1100000&fromSeriesID=110">Learn django), In url.py file i write the following urls...
urlpatterns = patterns('',
(r'^wikicamp/(?p<page_name>[^/]+)/edit/$','wikiapp.wiki.views.edit_page'),
(r'^wikicamp/(?p<page_name>[^/]+)/save/$','wikiapp.wiki.views.save_page'),
(r'^wikicamp/(?p<page_name>[^/]+)/$','wikiapp.wiki.views.view_page'),
)
But there is errror which i cant understand.
sre_Constants.error:Unexpected end of pattern.
(r'^wikicamp/(?p<page_name>[^/]+)/$','wikiapp.wiki.views.view_page'),
I use the Django-1.0.2-final.tar.gz
You need to use an uppercase P to capture named regexp groups:
urlpatterns = patterns('',
(r'^wikicamp/(?P<page_name>[^/]+)/edit/$','wikiapp.wiki.views.edit_page'),
(r'^wikicamp/(?P<page_name>[^/]+)/save/$','wikiapp.wiki.views.save_page'),
(r'^wikicamp/(?P<page_name>[^/]+)/$','wikiapp.wiki.views.view_page'),
)