Django: How do I handle urls with multiple apps - python

I have two apps: core and dm
Here's my code:
core/urls.py
urlpatterns = [
path('', views.index, name='index')
]
dm/urls.py
urlpatterns = [
path('', views.dm, name='dm'),
path('prices', views.dm_prices, name='prices')
]
mysite/urls.py
from core import views
from dm import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('core.urls')),
path("stripe/", include("djstripe.urls", namespace="djstripe")),
path('dm', include('dm.urls')),
path('dm/prices', include('dm.urls')),
]
And so, looking from the 404 page, I can see that the URLs he sees are:
admin/
[name='index']
stripe/
dm [name='dm']
dm prices [name='prices']
dm/prices [name='dm']
dm/prices prices [name='prices']
I would be really happy if someone could explain to me how django reads the different URLs and how it orders them.
Thanks a lot!

First of all, you don't need to include urls of same app twice, include('<my_app>.urls') will include all the urls you mentioned in your app's urlpatterns. So 'dm/prices' is redundant in your case, and changing it to this will do the job.
from core import views
from dm import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('core.urls')),
path('dm/', include('dm.urls')),
path("stripe/", include("djstripe.urls", namespace="djstripe")),
]
For more information about include() read this django docs

It's maybe a bit outside of the scope of your question, but is the 404 page the problem you would like to solve?
As Rustam Garayev said path('dm', include('dm.urls')), django includes all urls from that file (the same applies to those in the 'core' path). That's why they appear twice. You essentially created four paths:
<yoursite>/dm/ (namespace dm)
<yoursite>/dm/prices (namespace prices)
<yoursite>/dm/prices (namespace dm)
<yoursite>/dm/prices/prices (namespace prices)
The ordering is the same as in the file that imports the apps' urls, i. e. 1 and 2 are the result from your first include statement, 3 and 4 from the second.
By the way, I realized that you're importing two views functions (core.views and dm.views) and recommend to define an alias in order to avoid name clashes in case you have methods with the same name in them.
from core import views as cviews
from dm import views as dviews

Related

Reverse for 'hobbieswithCSS.html' not found. 'hobbieswithCSS.html' is not a valid view function or pattern name

I am trying to attach hobbieswithCSS.html file to my website, while using Django. I am a beginner when it comes to Django, so I have naturally came across some problems (in the title) like this.
I have this anchor tag on my homepage -
My Hobbies
I have this view in my views.py file -
def hobbieswithCSS(request):
return render(request,'basic_app/hobbieswithCSS.html')
I think, that the main problem will be with the urlpatterns in urls.py file, because I am not sure how to set it up. These are my urlpatterns -
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^admin/', admin.site.urls),
url(r'^basic_app/',include('basic_app.urls')),
url(r'^logout/$',views.user_logout,name='logout'),
url(r'^$', views.hobbieswithCSS, name='hobbieswithCSS'),
]
Could anybody please tell me, how could I change the code in order to make that hobbieswithCSS.html file display, when I am trying to run it on my server?
It must be:
My Hobbies
Without basic_app.
Also you have the same path for index and hobbies . You have to change your url path:
urlpatterns = [
url(r'^$', views.index, name='index'),
...
url(r'^hobbies/$', views.hobbieswithCSS, name='hobbieswithCSS'),
]
in your template update to
My Hobbies

Django Include() in urls.py with two apps

I believe this is a simple question but I am having a hard time figuring out why this is not working.
I have a django project and I've added a second app (sales). Prior to the second app, my urls.py simply routed everything to the first app (chart) with the following:
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('chart.urls')),
]
and it worked fine.
I have read the docs over and over a looked at many tutorials, so my impression is that I can simply amend the urls.py to include:
urlpatterns = [
path('admin/', admin.site.urls),
path('sales/', include('sales.urls')),
path('', include('chart.urls')),
]
and it should first look for a url with sales/ and if it finds that then it should route it to sales.urls, and if it doesn't find that then move on and route it to chart.urls. However, when I load this and type in 127.0.0.1:8000/sales, it returns the following error:
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/sales/
Raised by: chart.views.index
which tells me that it is not routing my sales/ url to sales.urls but to chart.urls. When I change path('', include('chart.urls')), to path('', include('sales.urls')), it does route it to sales.urls so I know that my sales.urls file is set up correctly.
I know this is probably an easy question but I cannot figure it out with anything I've read. Any help is appreciated.
chart.urls:
from django.urls import path, re_path
from . import views
urlpatterns = [
path('dashboard/', views.chart, name='dashboard'),
path('', views.index, name='index', kwargs={'pagename': ''}),
path('<str:pagename>/', views.index, name='index'),
]
sales.urls:
from django.urls import path
from . import views
urlpatterns = [
path('sales/', views.sales, name='Sales Dashboard'),
]
I think the correct url for the sales page in your case would be http://127.0.0.1:8000/sales/sales/.
This is because sales/ is then looking in the included sales.urls and not finding any urls at the root / (the only url included there is at sales/ (within sales/) so will be sales/sales/
Reply to an OLD question but may be useful for others...
from django.urls import path, include
dont for get to import include
Do this:
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^', include('chart.urls')),
url(r'^sales/', include('sales.urls')),
]
you are not doing it properly since you are not telling your app where go once it is loaded .this r'^' to go directly to chart.url url(r'^', include('chart.urls')),

Having issues with Django URL mapping

I am trying Django for an upcoming project and going through a tutorial and running into issue with defining URL paths. Below is the project structure showing the urls.py at the project root.
The urls.py in my timer package is pretty simple:
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]
However when I launch the application and navigate to localhost:8080/timer/ I am getting a 404. Any suggestions what I should be looking at?
You can try to change URLs in the settings of the whole project like this:
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^timer/$', include('timer.urls')),
]
As for the timer, the URLs will be like this:
urlpatterns = [
url(r'^$', views.index, name="index"),
]
Don't forget about r's in the url().
It turns out that I created the urls.py under a wrong folder. I misunderstood the instructions and created the urls.py in the same folder as manage.py. Once I add the new url pattern in the file projectdb/projectgb/urls.py, the issue is fixed. Thanks.

Django: point url behind root of app?

I am going through Django's tutorials (Django tutorial part 3) and I am at the part where we are adding views and urls.
In this demo app they add subviews for polls, e.g. /polls/34/ to get to the 34th poll. Quoting from the tutorial:
When somebody requests a page from your website – say, “/polls/34/”, Django will load the mysite.urls Python module because it’s pointed to by the ROOT_URLCONF setting. It finds the variable named urlpatterns and traverses the regular expressions in order. After finding the match at '^polls/', it strips off the matching text ("polls/") and sends the remaining text – "34/" – to the ‘polls.urls’ URLconf for further processing. There it matches r'^(?P<question_id>[0-9]+)/$', resulting in a call to the detail() view like so:
My question is as follows:
suppose you have a view that is related to your app, but where the url - prepended by the app name - makes less sense than just the new view by itself. How could you make a view (which is part of the app) start at a new path name.
This might be confusing so here is an example.
Suppose you have an app (decks) for decks users make out of a set of cards. Then /deck/regex would take you to a given deck. If someone wanted to see more information about a card in the deck then /decks/cards/regex makes less sense then /cards/regex as a card can be in multiple decks.
It isn't a perfect example, but I think it highlights what I am trying to do.
I had some type of URL for you:
1st:
# The url in Projects, which you have to include to link your app.
from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^table/', include('table.urls')),
]
This upper case is your code now:
# So you can change is to:
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^', include('table.urls',namespace="table")),
]
And then: in tables.urls.py you can do what ever you want:
urlpatterns = [ url(r'^$', views.index, name='index'),
url(r'^decks/(?P<pk>.*)$', views.decksView, name='decksView'),
url(r'^card/(?P<pk>.*)$', views.cardView, name='cardView'),
]
What you are saying can easily be done but it is not done so because it causes a lot of confusion with regards to routing.
Talking about your decks example. Lets say you are in an app called decks, where root urls.py file is this :
from django.conf.urls import url,include
from django.contrib import admin
from Decks import views as deckviews
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'/cards/regex^$',deckviews.get_card_information),
url(r'^decks/',include('deckviews.urls')),
]
and the urls.py in Decks app can be:
from django.conf.urls import url,include
import views
urlpatterns = [
url(r'^regex/',views.generate_decks)
]
Here is an example where to generate decks, the decks/regex calls the generate random decks from within the urls.py of the decks app meanwhile you get your desired cards/regex which points to the views inside the decks app but still has the url that you wish for.
This ways you can route any url to any function and thats the beauty of django. This is rarely used though as it creates a lot of confusion when the apps get bigger and more complex.
Hope this helps. Cheers!

Django "homepage" app urls.py issue

I am pretty new to Django and when I laid my site out I did it in the following way:
The project is a "portal" of sorts,
App 1 "home" is the app that houses the homepage, login, registration
and other "site-wide" functionality
App 2 "inventory" is a basic asset inventory
App 3 "dashboard" is a set of status dashboards based on assets in the inventory
Right now I am trying to add the login functionality and I have a main project urls.py that looks like this:
File: /portal/urls.py
from django.conf import settings
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^$', include('home.urls'), name='home'),
url(r'^admin/', include(admin.site.urls), name='admin'),
url(r'^inventory/', include('inventory.urls'), name='inventory'),
url(r'^dashboard/', include('dashboard.urls'), name='dashboard'),
url(r'^capacity/', include('capacity.urls'), name='capacity'),
)
My plan is to use the inclusion of .../home/urls.py to manage any site-wide functionality such as logging in, registering, etc.
Right now the home index view shows just fine, but anything else in .../home/urls.py gives me a 404
File: /home/urls.py
from django.conf.urls import patterns, url
from home import views
urlpatterns = patterns('',
url(r'^test/$', views.index, name='home_test'),
url(r'^ajax_login/$', views.ajax_login, name='ajax_login'),
url(r'^$', views.index, name='home_index'),
)
At this point I suppose my question is two-fold: Am I approaching this correctly? If so, how can I get the desired functionality? If not, how should I change the way things are set up/laid out to do it the correct "best practices" way?
Thanks in advance!
EDIT
Got it working thanks to dt0xff and holdenweb, accepted holdenweb's answer since it was more accurate including the need to put the home url inclusion below the rest.
Here is my new portal/urls.py file for reference
File: /portal/urls.py
from django.conf import settings
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls), name='admin'),
url(r'^inventory/', include('inventory.urls'), name='inventory'),
url(r'^dashboard/', include('dashboard.urls'), name='dashboard'),
url(r'^capacity/', include('capacity.urls'), name='capacity'),
url(r'^', include('home.urls'), name='home'),
)
The issue is with your first pattern, which will only match the empty URL. So any empty URL will cause the home/urls.py URLs to be analyzed, but only the empty one will match even in that.
Unfortunately if there is no common prefix then that pattern "^" will match every URL (since they all start at the beginning ...).
So you should either use a common prefix for all the pages, or put the home URL specification at the end to give the other URLs a chance to match before it is tested.
Django looks in urls like this:
Get list of root urls - portal/urls
Find first, which matches to current url
If it is include, go to included urls, cutting off matched part
Your problem is here
url(r'^$', include('home.urls'), name='home'),
I mean, here
'^$'
You want url to match "start and then end of url". It works good with root(dunno.com/), but not with others, because url will contain something more...
So, just remove $ and you are fine
url(r'^', include('home.urls'), name='home'),
you never need to add regex($) at project/urls.py

Categories

Resources