Redirect to named url pattern directly from urls.py in django? - django

In Django, how can I do a simple redirect directly from urls.py? Naturally I am a well organized guy, favoring the DRY principle, so I would like to get the target based on it's named url pattern, rather than hard coding the url.

If you are on Django 1.4 or 1.5, you can do this:
from django.core.urlresolvers import reverse_lazy
from django.views.generic import RedirectView
urlpatterns = patterns('',
url(r'^some-page/$', RedirectView.as_view(url=reverse_lazy('my_named_pattern'), permanent=False)),
...
If you are on Django 1.6 or above, you can do this:
from django.views.generic import RedirectView
urlpatterns = patterns('',
url(r'^some-page/$', RedirectView.as_view(pattern_name='my_named_pattern', permanent=False)),
...
In Django 1.9, the default value of permanent has changed from True to False. Because of this, if you don't specify the permanent keyword argument, you may see this warning:
RemovedInDjango19Warning: Default value of 'RedirectView.permanent' will change from True to False in Django 1.9. Set an explicit value to silence this warning.

This works for me.
from django.views.generic import RedirectView
urlpatterns = patterns('',
url(r'^some-page/$', RedirectView.as_view(url='/')),
...
In above example '/' means it will redirect to index page,
where you can add any url patterns also.

for django v2+
from django.contrib import admin
from django.shortcuts import redirect
from django.urls import path, include
urlpatterns = [
# this example uses named URL 'hola-home' from app named hola
# for more redirect's usage options: https://docs.djangoproject.com/en/2.1/topics/http/shortcuts/
path('', lambda request: redirect('hola/', permanent=False)),
path('hola/', include("hola.urls")),
path('admin/', admin.site.urls),
]

I was trying to redirect all 404s to the home page and the following worked great:
from django.views.generic import RedirectView
# under urlpatterns, added:
url(r'^.*/$', RedirectView.as_view(url='/home/')),
url(r'^$', RedirectView.as_view(url='/home/')),

This way is supported in older versions of django if you cannot support RedirectView
In view.py
def url_redirect(request):
return HttpResponseRedirect("/new_url/")
In the url.py
url(r'^old_url/$', "website.views.url_redirect", name="url-redirect"),
You can make it permanent by using HttpResponsePermanentRedirect

You could do straight on the urls.py just doing something like:
url(r'^story/(?P<pk>\d+)/',
lambda request, pk: HttpResponsePermanentRedirect('/new_story/{pk}'.format(pk=pk)))
Just ensure that you have the new URL ready to receive the redirect!!
Also, pay attention to the kind of redirect, in the example I'm using Permanent Redirect

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.

NoReverseMatch on Django even when kwargs are provided

The Django cant resovle the url, even though the expected kwarg is provided.
Here is root urls.py:
from django.conf import settings
from django.conf.urls import include, url
from django.conf.urls.static import static
from django.contrib import admin
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^media/(?P<path>.*)$','django.views.static.serve',{'document_root': settings.MEDIA_ROOT}),
url(r'^ckeditor/', include('ckeditor_uploader.urls')),
url(r'^static/(?P<path>.*)$','django.views.static.serve',{'document_root': settings.STATIC_ROOT}),
url(r'^(?P<domain>\w+)', include('frontend.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Here is frontend urls.py:
from django.conf.urls import include,patterns,url
from . import views
from .views import MyprofileView
from .views import SuccessView
from .views import CompanyView
from .views import SubscriptionView
from django.views.decorators.csrf import csrf_exempt
urlpatterns = patterns('',
url(r'/success(/?)$', SuccessView.as_view(), name='success'),
url(r'/subscribe(/?)$', SubscriptionView.as_view(), name='subscribe'),
url(r'^(/?)$', MyprofileView.as_view(), name='home'),
url(r'/api/v1/', include('cpprofile.api.urls')),
url(r'/product', include('product_information.urls')),
url(r'/corporations/(?P<company>\d+)$', CompanyView.as_view(), name='company_page'),
url(r'^/(?P<subscription>\w+)/product/pay/return/(?P<amount>\d+)/(?P<currency>\w+)/(?P<id>\d+)?$',
views.payment_return, name='subscription_product_payment_return'),
)
And here is how I am trying to reverse call it in view.py MyprofileView:
context['subscribe_url'] = redirect('subscribe', kwargs={'domain': 'up'})
What could be wrong here?
Thanks
UPDATE 1
Here is the error I am getting:
django.core.urlresolvers.NoReverseMatch
NoReverseMatch: Reverse for 'subscribe' with arguments '()' and keyword arguments '{'domain': 'up'}' not found. 1 pattern(s) tried: ['(?P<domain>\\w+)/subscribe(/?)$']
You have to unpack the kwargs.
Solution:
kwargs = {'domain': 'up'}
redirect('app_name:subscribe', **kwargs)
EDIT: This will work, no need to change the url.
EDIT2: Prepend app's name and a colon to url name. This finds the url in the app namespace.
Ref: Redirect in Django
I suspect it's because of the (/?). That captures either '' or '/'. So you have to pass that as a non-keyword argument:
redirect('subscribe', '/', domain='up')
So this is in addition to what Sachin Kukreja says.
You need to use reverse to get the correct URL, and then redirect to that.
from django.core.urlresolvers import reverse
return redirect(reverse('subscribe', kwargs={'domain': 'up'}))
In your case, where you seem to be trying to assign the url to a context variable, you shouldn't use redirect at all. Reverse resolves the URL, redirect returns a response.
context['subscribe_url'] = reverse('subscribe', kwargs={'domain': 'up'})
Might also want to follow best practices with your urlconf for consistency, namely end all patterns with '/', but don't start any with '/'. As you do for most of them in the root config:
url(r'^admin/', include(admin.site.urls)), <-- good

django urls: "Django tried these URL patterns"

I am trying a tutorial on Django called blog. I have the following structure:
FirstBlog|FirstBlog
settings
urls
__init__
etc
blog
templates | index.html
migrations
views.py
manage.py
The view.py has
from django.shortcuts import render
from django.shortcuts import render_to_response
from blog.models import posts
def home(request):
return render('index.html')
The urls.py has
from django.conf.urls import url
from django.conf.urls import include
from django.contrib import admin
urlpatterns = [
url(r'^blog', 'FirstBlog.blog.views.home',name='home'),
]
and I get this error:
Using the URLconf defined in FirstBlog.urls, Django tried these URL patterns, in this order: ^blog [name='home']
The current URL, , didn't match any of these.
I can't seem to get it right..
Any help would be appreciated.
Thank you,
You are requesting for / url and you have not saved any such mapping. Current mapping is for /blog . So it will work for the same url.
i.e goto the browser and request /blog
If you need it to work for / then change the urls appropriately.
within your blog app, create a urls.py file and add the following code which calls the home view.
blog/urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
#url(r'^',views.home, name='home'),
]
then in your root urls file which can be found at FirstBlog/urls.py
from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
url(r'^blog/',include('blog.urls')), #when you visit this url, it will go into the blog application and visit the internal urls in the app
]
PS:
your templates should be in blog/templates/blog/index.html
Read this docs on templates to understand how django locates templates.
This one is to understand how urls work Urls dispatcher
You are doing this in the wrong way! Try doing that using TemplateView from class-based views, which are the current standard from django views.
Check the django documentation: https://docs.djangoproject.com/en/1.9/topics/class-based-views/
Use this at the urls.py:
from django.conf.urls import url
from django.views.generic import TemplateView
urlpatterns = [
url(r'^blog/', TemplateView.as_view(template_name="index.html")),
]
And then, create a folder called templates in the project root ( like this: https://docs.djangoproject.com/en/1.9/intro/tutorial03/#write-views-that-actually-do-something ) named index.html
Simply go to file then select Save all your project instead of save. Or use shortcut Ctrl +k s on windows. Project should be able to sync and display the code on Django interface

Django URL not working as expected

I have a URL that does not work, for some reason. I get a 404, "'new' could not be found". Here is my urls.py:
url(r'^assets/new', 'watershed.views.new_asset', name='new_asset'),
There is a lot more in my urls.py but this is the ONLY one that contains the word, "assets" in it. If I change this url to anything/new, it works. If i misspell assets (assettss/new), it works. If I take out the /new and just use "assets", it also works fine. In my views folder I have an __ init __.py which contains the following:
from groups import *
from members import *
from leave_group import *
from payments import *
from assets import *
I also have an assets.py, which contains the following:
from django.contrib.auth.decorators import login_required
from watershed.models import Member, Org, OrgToMember, Asset
from django.shortcuts import render, redirect
from django.contrib.auth.models import User
def new_asset(request):
return render(request, 'asset_add.html')
I have no idea what Django does not like about assets/new.
UPDATE: Here is my full urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
# Examples:
url(r'^', include('outside.urls')),
url(r'^blog', include('blog.urls')),
url(r'^admin', include(admin.site.urls)),
url(r'^logout', 'watershed.views.logout', name='logout'),
url(r'^register/create', 'watershed.views.create', name='create'),
url(r'^register', 'watershed.views.register', name='register'),
url(r'^translog/(\d+)', 'watershed.views.translog', name='translog'),
url(r'^settings', 'watershed.views.settings', name='settings'),
# Group URIs
url(r'^groups/(\d+)/leave', 'watershed.views.leave_group', name='leave_group'),
url(r'^groups/(\d+)/dissolve', 'watershed.views.dissolve_group', name='dissolve_group'),
url(r'^groups/new', 'watershed.views.add_group_form', name='add_group_form'),
url(r'^groups/(\d+)', 'watershed.views.dashboard', name='dashboard'),
url(r'^groups/add', 'watershed.views.add_group', name='add_group'),
url(r'^groups', 'watershed.views.groups', name='groups'),
# Member URIs
url(r'^members/(\d+)', 'watershed.views.profile', name='profile'),
url(r'^member/login', 'watershed.views.login', name='login'),
# Payments URIs
url(r'^payments', 'watershed.views.payments', name='payments'),
# Asset URIs
url(r'^assets/new', 'watershed.views.new_asset', name='new_asset'),
You new_assets function containts in assets.py file, buy you import this function from views.py file. Use this:
url(r'^assets/new', 'path.to.assets.new_asset', name='new_asset'),
I figured it out. The problem is that my static url in my settings.py is - wait for it:
STATIC_URL = '/assets/'
So, clearly, one of those must change.

"No module named simple" error in Django

ImportError at /
No module named simple
Django Version: 1.5.dev20120710212642
I installed latest django version. I am using
from django.views.generic.simple import redirect_to
in my urls.py. What is wrong? Is it deprecated?
Use class-based views instead of redirect_to as these function-based generic views have been deprecated.
Here is simple example of class-based views usage
from django.conf.urls import patterns, url, include
from django.views.generic import TemplateView
urlpatterns = patterns('',
(r'^about/', TemplateView.as_view(template_name="about.html")),
)
Update
If someone wants to redirect to a URL, Use RedirectView.
from django.views.generic import RedirectView
urlpatterns = patterns('',
(r'^one/$', RedirectView.as_view(url='/another/')),
)
this should work
from django.conf.urls import patterns
from django.views.generic import RedirectView
urlpatterns = patterns('',
url(r'some-url', RedirectView.as_view(url='/another-url/'))
)
Yes, the old function-based generic views were deprecated in 1.4. Use the class-based views instead.
And for the record (no relevant example currently in documentation), to use RedirectView with parameters:
from django.conf.urls import patterns, url
from django.views.generic import RedirectView
urlpatterns = patterns('',
url(r'^myurl/(?P<my_id>\d+)$', RedirectView.as_view(url='/another_url/%(my_id)s/')),
)
Please note that although the regex looks for a number (\d+), the parameter is passed as a string (%(my_id)s).
What is still unclear is how to use RedirectView with template_name in urls.py.