I've got a django urls.py file like so:
Base file:
urlpatterns = patterns('',
(r'^', include('sp.sp_app.urls')),
(r'^', include('sp.sp_api_activity.urls')),
(r'^', include('sp.sp_api_player.urls')),
(r'^', include('sp.sp_web.urls')),
)
In the sp.sp_web.urls file, I have the following:
from django.conf.urls.defaults import *
urlpatterns = patterns('superproof.superproof_web.views',
(r'^$','index'), #Shows your home page
(r'^challenge$','spcreatechallenge'),
(r'^player/`$','getlastactivity'),
(r'^yearlysummary/','yearlysummary'),
(r'^processchallenge$','processchallenge'),
(r'^activity/(\w{32})$','activitydetail'),
)
The yearlysummary url is loading sometimes. Other times, I get a 404 error. This happens with the exact same valid URL. I don't change anything in the URL, or in the code.
When I get the 404 error with debug turned on, my yearlysummary URL pattern isn't on the list.
Any ideas?
A couple things I noticed that could be an issue...
I notice you are not namespacing your included urls for each app. Not knowing what the other urls modules look like, I can assume its possible that you can have colliding urls. I Would recommend doing something like this:
urlpatterns = patterns('',
(r'', include('sp.sp_app.urls')),
(r'^activity/', include('sp.sp_api_activity.urls')),
(r'^player/', include('sp.sp_api_player.urls')),
(r'^web/', include('sp.sp_web.urls')),
)
Normally when you have url includes, they are for different apps, so you would want to namespace them to avoid two apps specifying the same url pattern.
Also, whats that back-tick in one of your urls? Did you mean to expect that?
(r'^player/`$','getlastactivity'),
jdi is spot on, on the analysis. I'll try to explain why exactly is there the issue, in your case.
You will notice that if you include (r'^', include('sp.sp_web.urls') as the first pattern in the main urls.py, your view will rightly load always.
When you have it as the last pattern, the reason it doesn't match the other times is that, that pattern is matching some other pattern in the earlier pattern, say [/w+]. The debug page, on a 404 of the url pattern, displays all the sub-url patterns of one of the patterns it matches. This is exactly why the pattern isn't on the urls displayed on the debug page.
Like jdi mentions it is a good practice to namespace the urls properly, so this doesn't occur. You can probably do it even without namespacing, but your regexes have to be proper, with the end character $ included, at least.
Related
Previous working configuration of urls.py:
I'm not using include. Previously, a configuration of the project's url.py like this has worked perfectly for me:
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^$', 'projectName.appName.views.view1'),
url(r'^about/$', 'projectName.appName.views.view2'),
url(r'^contact/$', 'projectName.give.appName.view3'),
url(r'^contact/thanks/$', 'projectName.appName.views.view4'),
)
Current configuration of urls.py on separate project:
However, I seem to be facing inconsistent results with this other configuration on another project.
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^foo/$', 'projectName.appName.views.view1'),
url(r'^foo/bar1/', 'projectName.appName.views.view2'),
url(r'^foo/bar2/', 'projectName.appName.views.view3'),
)
What's wrong:
For example, when I visit the URL at /foo/bar1, it inconsitently either brings me to the desired URL or loads up /foo/ instead while still having /foo/bar1 displayed in the URL bar in the browser.
/foo/bar2/ mostly (19 out of 20 times) returns a 404 when that URL is requested. Otherwise it shows /foo/ but the original URL remains in the browser. It just seems so weird and odd, and this has never happened to me in Django before.
If you noticed the missing $'s, I found out through experimentation that this configuration is slightly more reliable. With the $'s, all my URLs end up loading /foo/ while still showing the requested URL in the browser.
I guess that it's worthy to note that /foo/ and /foo/bar1/ were mostly working fine (but calling /foo/bar1/ in the browser would still load up /foo/ instead perhaps 1 out of every 20 times called or so) until I added /foo/bar2/.
How now brown cow:
I guess this would have to do with regexes, but I'm not sure how should I be handling regexes to make this work, other than to follow what I've done before that was right but now can't work. Yeah so I don't know how does regex work.
If someone could point me in the right direction or tell me where might I have gone wrong that would be very helpful. Thank you!
Other info:
I'm developing on Python 2.7, Django 1.3.7 on PythonAnywhere, not locally.
Hi thanks for looking into this.
I have been following Django's tutorial on URLs and got a bit confused/stuck on this part:
https://docs.djangoproject.com/en/1.4/intro/tutorial03/#decoupling-the-urlconfs
what I do not understand is if, say, on page mypage.com I provide only 2 possible URLs for mypage.com/polls and mypage.com/admin, what happens if the user goes to mypage.com? Obviously, I thought, the user will need to see some sort of 'welcome' page so I decided to add another URL to that urls.py:
urlpatterns = patterns('',
url(r'^/', 'myapp.views.welcome'), #when it's just mysite.com
url(r'^myapp/', include('myapp.urls')), #includes everything with mysite.com/myapp/...
url(r'^admin/', include(admin.site.urls)),
)
But then I get redirected to that welcome view from whichever page, whether i go to /myapp or not. So, I decided to create a views.py file outside myapps folder and put that welcome page there, and it seems to have worked, apart from that I get a 404.
I am so confused! Could you explain in lamers' terms please
Thanks,
blargie-bla
It should be
url(r'^$', 'myapp.views.welcome')
otherwise any URL will match the pattern. Django will call the view for the first pattern in urlpatterns that matches, so you need to be specific and include the end-of-the-line character ($) into the pattern.
I'm trying to use django-cms app hooks in a different way. I have only an app, with different website pages. For each page, i created an AppHook, since i want to have control of all of them with the cms.
To do that, inside the app, i did a package, with urls.py file for each of the page, example:
/urls
/home_urls.py
/portfolio_urls.py
/contacts_urls.py
Here are the definition of some app hooks:
class WebsiteHome(CMSApp):
name = _("cms-home")
urls = ["website.urls.home_urls"]
apphook_pool.register(WebsiteHome)
class WebsiteServices(CMSApp):
name = _("cms-services")
urls = ["website.urls.services_urls"]
apphook_pool.register(WebsiteServices)
Anyway, the problem is: i don't have any control on the regular expressions. Each one, is entering on the first regular expression that it founds, in this case, the urlpattern in the
website.urls.home_urls
Despite, having different apphHooks.
Example:
if i write a slug contacts (that has an apphook to WebsiteContacts), it still goes to the home_urls.py file, associated with the WebsiteHome (app hook).
Did anyone had a similiar problem?
Basically, what I'm trying to say is that it's something wrong with the regular expression. I can't make:
url(r'^$', [...]),
only:
url(r'^', [...]),
If I put the '$', it doesn't enter on any regex. If I take it, it enters always on the
website.urls.home_urls.py
Despite the slugs having different Apphooks, associated with different urls.py files.
Have you tried r'^/$'? I'm using r'^/?$' in some app-hook urls, but I wonder if r'^$' is failing for you because of a '/'?
As you've defined each of those URL files as individual app hooks in CMS then they'll each get attached to a certain page in the CMS e.g.
www.mysite.com/home
www.mysite.com/contacts
www.mysite.com/services
etc
Because those URL files are attached to pages this should prevent conflict between urlpatterns. For example, I've got an URLs file attached to a CMS app called News which looks like this;
urlpatterns = patterns(
'',
url(r'^(?P<slug>[-_\w]+)/$', NewsDetailView.as_view(), name='news_detail'),
url(r'^$', NewsListView.as_view(), name='news_list'),
)
Which is attached to a page at mysite.com/news so if I go to mysite.com/news/myslug I hit that NewsDetailView and if I go to mysite.com/news I hit NewListView.
Using this example, if you had a slug for a contact you'd go to mysite.com/contacts/contact-slug to hit that NewsDetailView.
And just a sidenote on the urlpatterns in case you're not aware, the ^ in the regex signifies the start of a pattern to match, and the $ signifies the end. URL dispatcher docs
I'm working with Django, admittedly for the first time doing anything real.
The URL config looks like the following:
urlpatterns = patterns('my_site.core_prototype.views',
(r'^newpost/$', 'newPost'),
(r'^$', 'NewPostAndDisplayList'), # capture nothing...
#more here... - perhaps the perma-links?
)
This is in an app's url.py which is loaded from the project's url.py via:
urlpatterns = patterns('',
# only app for now.
(r'^$', include('my_site.core_prototype.urls')),
)
The problem is, when I receive a 404 attempting to utilize newpost, the error page only shows the ^$ -- it seems to ignore the newpost pattern...
I'm sure the solution is probably stupid-simple but right now I'm missing it. Can someone help get me on the right track...
Your pattern for the include will only match an empty URL string, change it to a prefix which should be mapped to the included urls, or remove the $ from that pattern.
I am trying to refactor out my application a little bit to keep it from getting too unwieldily. So I started to move some of the urlpatterns out to sub files as the documentation proposes.
Besides that fact that it just doesn't seem to be working (the items are not being rerouted) but when I go to the admin, it says that 'urlpatterns has not been defined'.
The urls.py I have at the root of my application is:
if settings.ENABLE_SSL:
urlpatterns = patterns('',
(r'^checkout/orderform/onepage/(\w*)/$','checkout.views.one_page_orderform',{'SSL':True},'commerce.checkout.views.single_product_orderform'),
)
else:
urlpatterns = patterns('',
(r'^checkout/orderform/onepage/(\w*)/$','commerce.checkout.views.single_product_orderform'),
)
urlpatterns+= patterns('',
(r'^$', 'alchemysites.views.route_to_home'),
(r'^%s/' % settings.DAJAXICE_MEDIA_PREFIX, include('dajaxice.urls')),
(r'^/checkout/', include('commerce.urls')),
(r'^/offers',include('commerce.urls')),
(r'^/order/',include('commerce.urls')),
(r'^admin/', include(admin.site.urls)),
(r'^accounts/login/$', login),
(r'^accounts/logout/$', logout),
(r'^(?P<path>.*)/$','alchemysites.views.get_path'),
(r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root':settings.MEDIA_ROOT}),
The urls I have moved out so far are the checkout/offers/order which are all subapps of 'commerce' where the urls.py for the apps are so to be clear.
/urls.py in questions (included here)
/commerce/urls.py where the urls.py I want to include is:
order_info = {
'queryset': Order.objects.all(),
}
urlpatterns+= patterns('',
(r'^offers/$','offers.views.start_offers'),
(r'^offers/([a-zA-Z0-9-]*)/order/(\d*)/add/([a-zA-Z0-9-]*)/(\w*)/next/([a-zA-Z0-9-)/$','offers.views.show_offer'),
(r'^reports/orders/$', list_detail.object_list,order_info),
)
and the applications offers lies under commerce.
And so the additional problem is that admin will not work at all, so I'm thinking because I killed it somewhere with my includes.
Things I have checked for:
Is the urlpatterns variable accidentally getting reset somewhere (i.e. urlpatterns = patterns, instead of urlpatterns+= patterns)
Are the patterns in commerce.urls valid (yes, when moved back to root they work).
So from there I am stumped. I can move everything back into the root, but was trying to get a little decoupled, not just for theoretical reason but for some short terms ones.
Lastly if I enter www.domainname/checkout/orderform/onepage/xxxjsd I get the correct page. However, entering www.domainname/checkout/ gets handled by the alchemysites.views.get_path.
If not the answer (because this is pretty darn specific), then is there a good way for troubleshoot urls.py? It seems to just be trial and error. Seems there should be some sort of parser that will tell you what your urlpatterns will do.
Adding the following line in my urls.py worked for me:
from django.conf.urls import include
Have a look at the django docs for including other url confs. I think you might have misunderstood them. In particular
Whenever Django encounters include(), it chops off whatever part of the URL matched up to that point and sends the remaining string to the included URLconf for further processing.
As an example, you have
(r'^/checkout/', include('commerce.urls')),
(r'^/offers',include('commerce.urls')),
(r'^/order/',include('commerce.urls')),
This means that
/checkout/offers/
/offers/offers/
/order/offers/
will all match the url pattern (r'^offers/$','offers.views.start_offers') in commerce/urls.py.
If you want to define a view for /checkout/ in commerce.py, you need to add the pattern
(r'^$', 'path_to_your_view')
because the /checkout/ part will be chopped off by the include()
As, an aside:
In /commerce/urls.py, use
urlpatterns = patterns('',
...
for the first patterns you define. You can then use urlpatterns += later in the same file.