Using a name for dummy url patterns in django - django

I have a project with an app named exams. Right now my index page is the index page of one of these apps. So the url patterns is something like this:
from django.conf.urls import patterns, include, url
urlpatterns = patterns('',
url(r'^', include('exams.urls', namespace="exams")),
)
However it is possible that in future I want to create a new view for my index page and change the url patterns to something like this:
from django.conf.urls import patterns, include, url
urlpatterns = patterns('',
url(r'^exams/', include('exams.urls', namespace="exams")),
url(r'^/$', 'mysite.views.index', name="index"),
)
I want to create some links in my template to index whether it loads the exams app or another view. So I tried to use the name argument for the url method(like above) but it seems it's not working. When I use {% url 'index' %} in my template it returns the following error:
Reverse for 'index' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []
UPD: I forgot to mention that I tried using the following code:
from django.conf.urls import patterns, include, url
urlpatterns = patterns('',
url(r'^', include('exams.urls', namespace="exams"), name="index"),
)
And I got the error I wrote above.
UPD2: To clarify the problem more:
Right now when I go to http://mydomain/ I'll see my app index. But maybe in the future I like to change my index page and use another view for creating it. So when I go to http://mydomain/ I'll see the page rendered by that view and by going to http://mydomain/exams I'll see my apps index pages. In that case my urls.py will be sth like the second code I wrote above in which I can easily link to index page using {% url 'index' %} tag. However for now I'm using the code I wrote in my first update. I want my templates to render {% url 'index' %} as a link to my index page(instead of using {% url 'exams:index' %} so when I later change the urls.py code I won't have to change all of my templates.

If I understand well, you want an index view that could be easily changed, while not changing the links pointing to it in your templates. You can use your index view as a wrapper for other views ie:
def a_view_that_will_show_all_the_exams(request):
# this is the page displayed for now as default, but this could change
# some logic here
def another_view_that_could_become_the_home_page(request):
# some logic here
def index(request):
return a_view_that_will_show_all_the_exams(request)
# or another_view_that_could_become_the_home_page
# or return exams.views.whatever_view
This way you can easily change the result of the index view while keeping your links static.

If I understood you correctly, right now you don't have a url with the name index, in his case it is normal that when the template renders, it tries to find a url named index, and when it doesn't find it, it fails. What you might need is create the url and redirect to another view for now, like explained here:
Redirect to named url pattern directly from urls.py in django?
UPDATE:
I'm still not completely sure of what you want (sorry about that), but I suspect what you want to do is something similar to this:
from django.conf.urls import patterns, include, url
from django.core.urlresolvers import reverse_lazy
from django.views.generic import RedirectView
urlpatterns = patterns('',
url(r'^exams/', include('exams.urls', namespace="exams")),
url(r'^/$', RedirectView.as_view(url=reverse_lazy('exams:index'), name="index"),
)
The solution that Raphael is giving you is similar, but the user will not be redirected (with both urls the user will see the same content). Maybe that is what you are looking for?

Related

Python - Django add multiple urlpatterns for multiple views of template

I'm very very new to Python 3 and Django and I get to the following problem: I use a standard Template and now how to set it up when there is 1 view. But I don't get the code right for multiple views. I currently run the page locally
At the moment I have tried to change different orders within urlpatterns, and they do work when only 1 url in in there, but I can't get the second one in
views.py
from django.shortcuts import render, render_to_response
# Create your views here.
def index(request):
return render_to_response('index.html')
def store(request):
return render_to_response('store.html')
urls.py
from django.conf.urls import include, url
from django.contrib import admin
from myapp import views as views
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^store/$', views.store, name='store'),
url(r'^admin/', admin.site.urls)
]
urlpatterns += staticfiles_urlpatterns()
I would like the url pattern that lets me go to the index view and the store view
EDIT:
Full code is shared via: https://github.com/lotwij/DjangoTemplate
The error in the comments shows you are going to http:/127.0.0.1:8000/store.html, but your URL pattern url(r'^store/$', ...) does not include the .html, so you should go to http:/127.0.0.1:8000/store/.
The Django URL system uncouples the URL from the name of the template (sometimes the view doesn't even render a template!). You could change the regex to r'^store.html$ if you really want .html in the URL, but I find the URL without the extension is cleaner.

django 1.10 one app page with a link redirect to another app page

I'm new to django server and trying to build a simple website for user registration. Here is the problem, I create my own app with index.html as my homepage. I also used another user registration app from:
https://github.com/pennersr/django-allauth/tree/master/allauth
I was trying to add the app to my homepage with a 'sign up' link. Basically, the account part, and ideally, the link can direct to: http://127.0.0.1:8000/accounts/login/
However, when I run the server, it gives me error:
Reverse for 'base' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []
server result:
Both apps work fine individually, but when I try to add the link to my homepage, the error occurs.
The related code in index.html file in my first app:
<li>Log In</li>
The full path for index.html in my project is:
project/app1/templates/app1/index.html
The full path for base.html in my project is:
project/allauth/templates/base.html
I know I probably need to add a url line in my first app's urls.py file, and a view to show it, but how can I do it? Can anyone help me with this, much appreciate.
<li>Log In</li>
this line uses URL reversing, 'allauth:base' is the URL patterns, allauth prefix is the namespace, base is the named URL. You must define the namespace and named URL in the urls.py first.
Define your namespace in project's urls.py file like this:
from django.conf.urls import include, url
urlpatterns = [
url(r'^author-polls/', include('polls.urls', namespace='author-polls')),
url(r'^publisher-polls/', include('polls.urls', namespace='publisher-polls')),
]
Define your named URL in app's urls.py file like this:
from django.conf.urls import url
from . import views
app_name = 'polls'
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^(?P<pk>\d+)/$', views.DetailView.as_view(), name='detail'),
...
]
all the help you need is in this document: Naming URL patterns

urls.py structure for Django music app

I'm having some issues with the structuring of my Django app's urls.py file.
My project is a basic music player app. You begin by clicking a link for Music, followed by (for example) Artists, then you choose an artist, such as Weezer. The app then displays a list of albums and songs by that artist, rendered on the artist_name.html template by the views.artist_name function.
So far in the navigation of the app, the URL will look like http://localhost/music/artists/Weezer/.
My problem lies with the encoding of the next URL. If I choose the album The Blue Album by Weezer, I return the URL: http://localhost/music/artists/Weezer/The%20Blue%20Album.
This should render a template called artist_album_title.html using the views.artist_album_title function. Instead, it renders the new page using the same views.artist_name function as on the current page.
What seems to be happening is that the regex pattern for the ...Weezer/The%20Blue%20Album/ isn't matching with its related URL pattern in my urls.py file. Being new to Django (and with minimal experience with regex), I'm having a hard time determining what my urls.py file should look like for this kind of app.
Below is my urls.py file as it currently stands. Any help at all with my problem would be welcomed. Thanks guys.
from django.conf.urls import patterns, include
from music.views import home, music, artists, artist_name, artist_album_title
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
(r'^admin/', include(admin.site.urls)),
(r'^$', home),
(r'^music/$', music),
(r'^music/artists/$', artists),
(r'^music/artists/([\w\W]+)/$', artist_name),
(r'^music/artists/([\w\W]+)/([\w\W]+)/$', artist_album_title),
)
artist_album_title function from views.py
def artist_album_title(request, album_title):
album_tracks = Track.objects.filter(album__title=album_title)
return render_to_response('artist_album_title.html', locals(), context_instance=RequestContext(request))
The problem with your urlpatterns is that the url /music/artists/Weezer/The%20Blue%20Album satisfies the first pattern so it doesn't go to the next one. This is because Django executes the patterns in the order they are specified.
In order for this to work you must switch the places of the two patterns like so:
urlpatterns = patterns('',
(r'^admin/', include(admin.site.urls)),
(r'^$', home),
(r'^music/$', music),
(r'^music/artists/$', artists),
(r'^music/artists/([\w\W]+)/([\w\W]+)/$', artist_album_title),
(r'^music/artists/([\w\W]+)/$', artist_name),
)
The best would be to use the following structure for your urls:
urlpatterns = patterns('',
(r'^admin/', include(admin.site.urls)),
(r'^$', home),
(r'^music/$', music),
(r'^music/artists/$', artists),
(r'^music/artists/(?P<artist_name>[\w\W]+)/(?P<album_title>[\w\W]+)/$', artist_album_title),
(r'^music/artists/(?P<artist_name>[\w\W]+)/$', artist_name),
)
and then your views definition will look like this:
def artist_album_title(request, artist_name,album_title):
and
def artist_name(request, artist_name):
you can read more about the named groups in the url in Django docs here
https://docs.djangoproject.com/en/dev/topics/http/urls/#named-groups

Django basic url slugifying issues

I want to slugify my urls in my Django application. I have read many documents but I am still not sure how to do it better. I have two questions:
How to call the same view for two different urls?
I would like to call home view for both www.mysite.com and www.mysite.com/index.html
(r'^$', 'myapp.main.views.home')
(r'([-\w]+)$', 'myapp.main.views.home')
The code above sounds good but of course it raises an error as home view expects 1 parameter but 2 is given. How can I resolve this?
I have so many apps and they all have their own urls.py file. I was handle them as including their urls file to the root urls.py as
(r'^warehouse/', include('myapp.warehouse.urls')),
In that way, urls seems like www.mysite.com/warehouse/blabla/
However, I want to slugify them as www.mysite.com/warehouse_blabla.html
Slugifying is not hard but how can I resolve such url and redirect it to the blabla view in warehouse app?
Thanks
Regarding the first problem, you would be better off using a redirect for the index.html URL (better for SEO etc.)
from django.views.generic.simple import redirect_to
urlpatterns = patterns('',
url(r'^$', 'myapp.main.views.home')
url(r'^index.html$', redirect_to, {'url': '/'}),
)
Regarding the second issue, your urls.py file is just a set of regular expressions, so you have control over the URL scheme you want to use:
urlpatterns = patterns('',
url(r'^warehouse_(?P<slug>[_w]+).html$', 'warehouse.views.warehouse_detail'),
)
That said, I think you would be better sticking to the usual convention of slashes

django reverse() failing

simply put mentions of reverse() anywhere in my project were failing, and so was {% url %}.
I have since made some progress if you scroll to the bottom!
relevant files
root/urls.py
from django.conf.urls.defaults import patterns, include, url
from django.contrib.staticfiles.views import serve as serveStatic
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
(r'^admin/', include(admin.site.urls)),
(r'^dbrowse/', include('dbrowse.urls')),
(r'^static/', serveStatic),
url(r'^$', 'core.views.viewHallo',name='home'),
)
root/core/views.py
from django.shortcuts import render_to_response
from django.template.context import RequestContext
from site import site_store
def viewHallo (request):
pass
return render_to_response ('core.html',
{'site':site_store,
'title':'i am the hallo view',
'content':'Hallo World!',},
context_instance=RequestContext(request))
Notes
I first noticed the reverse() failing when i had a file called site.py in my project that tried to call reverse(). I was using it to store site settings. I was using the file because
I didn't want to use the bother the database with data that would rarely change.
If I nuked my projects database I didn't want my site settings also going down
I have since found a way to use models to achieve the two goals.
but all that is just extra background info, in case you here someone commenting about a site.py.
update 25/02/11
well here goes!
first notice that urls.py has (r'^dbrowse/', include('dbrowse.urls')). that caused reverse() to fail. I'll explain later...
as for the template tag, I've discovered that the {% url %} doesnt take variables. I took this completely for granted.In fact when I was testing the template tag, i'd just go in and hard code something such as {% url 'home' %} which would work and sometimes i'd test {% url home %} with home being a variable. I din't even see this as being completely different test cases.
But i now know {% load url from future %} allows you to use variables as arguments to {% url %}
Anyway, now back to the (r'^dbrowse/', include('dbrowse.urls')) in urls.py
I had a folder like so
project\
--dbrowse\
__init__.py
urls.py
now this is dbrowse/urls.py
from django.conf.urls.defaults import patterns, url
#databrowse
from django.contrib import databrowse
databrowse.site.register(MyModel)
urlpatterns = patterns('',
url(r'(.*)',databrowse.site.root, name='dbrowse'),)
this was my attempt to avoid having to put databrowse.site.register(MyModel) in my project's root urls.py like the docs suggested. I dont like the idea of polluting my projects main urls.py with databrowse.site.register(MyModel)
however I still dont understand why this caused reverse() to break. but i'm supecting it's to do with (.*) being in the pattern.