Django URL pattern with different roots - python

I have two URL patterns that both exist in the same application that I'm working on getting set up.
I need urls like the following to work.
http://www.domain.com/p/12345
http://www.domain.com/s/12345
However, both of these live in the same django application.
My main urls.py looks something like this for handling the /p/12345 urls.
urlpatterns = patterns('',
(r'^p/', include('myproject.myapp.urls')),
)
and my urls.py for the application is similar. but this still only handles the /p/12345 urls.
urlpatterns = patterns('myproject.myapp.views',
(r'^(?P<object_id>\d+)/$', 'some_view'),
)
My issue is that both are almost identical but just have a different prefixes. How can I do this for both the /p/12345 and /s/12345 urls. I've read through the documentation but wasn't able to figure this one out. I've thought of 'sloppy' ways to do this with 2 urls.py files, but I know there must be a better way.

You can include a URLs file with an empty pattern. You could do this:
main urls.py
urlpatterns = patterns('',
(r'foo/', 'foo_view'),
(r'^', include('myproject.myapp.urls')),
)
app urls.py
urlpatterns = patterns('puzzlequest.pq.views',
(r'^p/(?P<object_id>\d+)/$', 'some_view'),
(r'^s/(?P<object_id>\d+)/$', 'other_view'),
)
Note that other routes (like foo/) have to come first.

Related

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!

Is it possible to serve a static html page at the root of a django project?

I have a django app hosted on pyhtonanywhere. The app resides at username.pythonanywhere.com/MyApp. I would like to serve a static html page at username.pythonanywhere.com. Is this possible? Essentially it would serve as an index linking to /MyApp, /MyApp2, and other future apps.
I can't seem to find any info on how to do this, but I assume I have to modify mysite/mysite/urls.py as navigating to root currently gives me a 404 with messages about failing to find a match in urls.
urlpatterns = [
url(r'^/$', ???),
url(r'^admin/', include(admin.site.urls)),
url(r'^MyApp/', indluce('MyApp.urls')).
]
The previous is my best guess (a bad one i know). That should (correct me if i'm wrong) match the root URL, but I have no idea how to say "hey django just look for a static file", or where that static html should live, or how to tell django where it lives.
Try not to cut my head off. I'm brand new to django.
P.S. I'm using django 1.8 in a virtualenv on PA
Of course you can. In cases where I just need to render a template, I use a TemplateView. Example:
url(r'^$', TemplateView.as_view(template_name='your_template.html'))
I usually order my URL patterns from most specific to least specific to avoid unexpected matches:
from django.views.generic import TemplateView
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^MyApp/', include('MyApp.urls')),
url(r'^$', TemplateView.as_view(template_name='your_template.html')),
]
As far as where Django looks for templates, it's up to your configuration to tell Django where to look: https://docs.djangoproject.com/en/1.8/topics/templates/#configuration
On PythonAnywhere, you can use the static files facility of your web app to serve the static file before it gets to Django:
Put a file called index.html in a directory and then point a static file entry to that directory. If the static file URL is / and the directory is the one with the html file in it, the file will be served at /.
Be aware that you don't want the directory to be above any of your code or you'll expose your code as static files i.e you don't want to use the directory /somewhere/blah if your code is in /somewhere/blah/code, you'll want to put it in /somewhere/no_code_here
I have been tinkering with Django version 3.2, and I was able to serve a static HTML page at the root of the project after creating a Django app as in their official tutorial like the following in the root urls.py file:
from django.views.generic import TemplateView
urlpatterns = [
path('polls/', include('polls.urls')),
path('admin/', admin.site.urls),
path('', TemplateView.as_view(template_name='home/base.html')),
]
This is given that home/base.html is placed where the default template folder is. If I simply re-use the polls templates directory I can create a folder like polls/templates/home/ to store base.html, for example.

Django media page not found 404

I'm trying to learn to work with Django and i'm making a image app.
Now I managed to upload images to my database, but now I want to retrieve them.
The images are stored in media/images/.
Now I made an admin page that looks like this:
AS you can see the thumbnails don't load.
When You click on one of those thumbnails, I get the following error:
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/media/images/june.png
Using the URLconf defined in mysite.urls, Django tried these URL patterns, in this order:
^admin/
The current URL, media/images/june.png, didn't match any of these.
Here is my urls.py of my main thinghy (not the app, wich is called photo):
from django.conf.urls import patterns, include, url
from django.contrib import admin
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'mysite.views.home', name='home'),
# url(r'^blog/', include('blog.urls')),
url(r'^admin/', include(admin.site.urls)),
)
Now I'm not sure what I exactly need to do to fix this.
I hope you can help me.
Please be clear ( small steps ) cause I'm not that experienced with django.
Thanks in advance
Oh BTW i'm on Win7
EDIT:
this is what I added to my settings/py
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/http://127.0.0.1:8000/media/'
So right now, your urls.py doesn't have a pattern for /media/images. That pattern probably exists somewhere in your photo app. You need to link the urls for your photo app into your primary urls.py, something like:
url(r'^media/', include('photo.urls')),
This would tell the app that if it sees a url with media/ it should look for the next thing ('images/') in the photo app.

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

Django - How to use URLconfs with an apps folder?

I'm following the tutorial on the Django website but I'm trying to expand upon it. I like the organizational scheme of putting all of your apps in an "apps" folder. I'm trying to figure out the proper way to include urls.py in order to get everything to link together.
Here's my root urls.py:
from django.conf.urls.defaults import *
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
(r'^polls/', include('apps.polls.urls')),
(r'^admin/', include(admin.site.urls)),
)
Here's my urls.py at apps/polls/urls.py:
from django.conf.urls.defaults import *
urlpatterns=patterns('polls.views',
(r'^polls/$', 'index'),
(r'^polls/(?P<poll_id>\d+)/$', 'detail'),
(r'^polls/(?P<poll_id>\d+)/results/$', 'results'),
(r'^polls/(?P<poll_id>\d+)/vote/$', 'vote'),
)
What's the correct way to do this? Thanks!
The way you currently have it set up... the URLs for polls would be:
http://your.url.here/polls/polls/235/results/
This is probably not what you want. The include function in the urlpatterns in the root urls.py file specifies "polls/" as a prefix to all urlpatterns in the polls app. Therefore, in the polls/urls.py file, you shouldn't specify the "polls/" prefix again as it will cause duplicate prefixes.
How are you running your Django instances? If you have multiple vhosts configured in Apache then each Django instance in /apps has it's own urls.py.
I got it to work by doing this:
urlpatterns=patterns('polls.views',
(r'^$', 'index'),
(r'^(?P<poll_id>\d+)/$', 'detail'),
(r'^(?P<poll_id>\d+)/results/$', 'results'),
(r'^(?P<poll_id>\d+)/vote/$', 'vote'),
)
I guess the polls part is taken care of in the root urlconf

Categories

Resources