NoReverseMatch on Django even when kwargs are provided - django

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

Related

Django not getting path not matching

I am trying to make a certain url on my localhost show "Alex!" when it is entered in. For some reason I am getting this error: "Using the URLconf defined in mysite.urls, Django tried these URL patterns, in this order:
admin/
The current path, sauce, didn’t match any of these."
The app name is "main"
Here is my code:
main.urls
from django.urls import path
from . import views
urlpatterns = [
path('sauce/', views.index, name='index'),
]
main.views
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
def index(request):
return HttpResponse("Alex!")
mysite.urls
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('sauce/', include('main.urls')),
path('admin/', admin.site.urls),
]
I also tried doing this but with the homepage and not "sauce/" but that didn't work either.
Your path is not matching because you have "sauce" in both main.urls and mysite.urls. When you use include the urls from main.urls will be appended to the path you specify in mysite.urls, so the combined url becomes:
http://127.0.0.1:8000/sauce/sauce
I would replace the "sauce/" in mysite.urls to just "".

Django URL mapping - NameError: name X is not defined

[A similar question was asked, but not marked as answered, here. I considered continuing that thread but the website told me I'm only supposed to post an answer, so it seems I have to start a new topic.] I'm trying to follow this tutorial and I'm having problems with the URL mapping. Specifically with the part described as "So best practice is to create an “url.py” per application and to include it in our main projects url.py file". The relevant, I hope, part of the folder structure, which arose by following steps of the tutorial to the letter (if possible; usage of the 'patterns' module was impossible for example) and using Django 1.10 is the following:
myproject/
myapp/
urls.py
views.py
myproject/
urls.py
The myproject/urls.py is as follows:
from django.conf.urls import include, url
from django.contrib import admin
admin.autodiscover()
from myapp.views import hello
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^myapp/', include(myapp.urls)),
]
The myapp/urls.py is as follows:
from django.conf.urls import include, url
urlpatterns = [
url(r'^hello/', myapp.views.hello),
]
The myapp/views.py is as follows:
from django.shortcuts import render
def hello(request):
return render(request, "hello.html", {})
However, running 'python manage.py runserver' results in the following error:
url(r'^myapp/', include(myapp.urls)),
NameError: name 'myapp' is not defined
INSTALLED_APPS in settings.py contains 'myapp'.
I'd be greatful for any tips on how to deal with the NameError! [Or any tips whatsoever that anyone might consider to be helpful!]
You have the NameError because you are referencing myapp in myproject/urls.py but haven't imported it.
The typical approach in Django is to use a string with include, which means that the import is not required.
url(r'^myapp/', include('myapp.urls')),
Since you have move the hello URL pattern into myapp/urls.py, you can remove from myapp.views import hello from myproject/urls.py.
Once you've made that change, you will get another NameError in myapp/urls.py. In this case, a common approach is to use a relative import for the app's views.
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^hello/$', views.hello),
]
Make sure you have imported following modules to urls.py.
from django.conf.urls import url
from django.contrib import admin
in django 2.0
use these
from django.contrib import admin
from django.urls import path
from first_app import views
urlpatterns = [
path('',views.index, name="index"),
path('admin/', admin.site.urls),
]
your app URL has to be a string
so, here is how the code should look like.
from django.conf.urls import include, url
from django.contrib import admin
admin.autodiscover()
from myapp.views import hello
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^myapp/', include('myapp.urls')),
]
also, note that from python 2 upward the regular expression is not needed.
change URL to path
from django.conf.URLs import include path
from Django.contrib import admin
admin.autodiscover()
from myapp.views import hello
urlpatterns = [
path('^admin/', include(admin.site.urls)),
path('^myapp/', include('myapp.urls')),
]
In Django 2.1.7 here is the default urls .py file
from django.contrib import admin
from django.urls import path
urlpatterns = [
path('admin/', admin.site.urls),
]
so we need to add this line as well
from django.conf.urls import url
I have followed #Alasdair answers
You have the NameError because you are referencing myapp in myproject/urls.py but haven't imported it.
The typical approach in Django is to use a string with include, which
means that the import is not required.
Unfortunately, it didn't work out(I still got the name X is not defined error). Here is how I do it.
from django.contrib import admin
from django.urls import include
from django.conf.urls import url
from article import urls as article_users
from article import urls as user_urls
urlpatterns = [
path('admin/', admin.site.urls),
path('api/article/', include(article_users)),
path('api/user/', include(user_urls)),
]
Before using the URL command be sure to first import the url from the module Urls. Then try using the runserver.
from django.conf.urls import url
from django.contrib import admin
from django.urls import path

Django NoReverseMatch url

I can't figure out why I'm returning the following error:
NoReverseMatch at /
Reverse for '' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []
Here is the link in my template:
<li>Home</li>
Here are my main urls:
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
(r'^', include('merged.catalog.urls')),
(r'^cart/', include('merged.cart.urls')),
(r'^checkout/', include('merged.checkout.urls')),
url(r'^admin/', include(admin.site.urls)),
)
Here is the sub urls:
from django.conf.urls import patterns, url, include
urlpatterns = patterns('merged.catalog.views',
(r'^$','index', {'template_name': 'catalog/index.html'}, 'catalog_home'),
)
It seems like everything is in order, but maybe I'm missing something obvious.
Some changes that might help.
In your template:
<li>Home</li>
In your urls.py
from django.conf.urls import patterns, url, include
urlpatterns = patterns('merged.catalog.views',
(r'^$','index', {'template_name': 'catalog/index.html'}, name='catalog_home'),
)

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.

Redirect to named url pattern directly from urls.py in 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