Reverse not found in Django - python

This might be a simple one but I have been on this for hours, I must be missing something. Here we go:
urls.py:
urlpatterns = [
# Event patterns
url('^$', views.BuddyProgram.as_view(), name='buddy_program'),
url('^dashboard/$', views.BuddyDashboard.as_view(), name='buddy_dashboard'),
url('^thank-you/$', views.BuddyFinal.as_view(), name='final'),
url('^completed_intro/$', views.CompletedIntro.as_view(), name='buddy_completed_intro'),
url('^completed_passive_track/$', views.CompletedPassiveTrack.as_view(), name='buddy_completed_passive_track'),
url('^about/$', views.BuddyAbout.as_view(), name='buddy_about'),
url('^list/$', views.Buddies.as_view(model=BuddyProfile), name='buddies'),
url('^signup/$', views.BuddySignupView.as_view(), name='buddy_signup'),
# url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
url(r'^(?P<buddy_id>[0-9]+)/$', views.Buddy.as_view(model=BuddyProfile), name='buddy'),
]
views.py:
class BuddyFinal(TemplateView):
template_name = 'buddy/thank_you.html'
class BuddySignupView(SignupView):
template_name = 'buddy/buddy_create.html'
success_url = reverse('final') # profile specific success url
form_class = BuddySignupForm
profile_class = BuddyProfile # profile class goes here
def form_valid(self, form):
response = super(BuddySignupView, self).form_valid(form)
profile = self.profile_class(user=self.user)
profile.save()
return response
and the error I get:
django.core.urlresolvers.NoReverseMatch: Reverse for 'final' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []

As your URLs aren't loaded yet when importing the BuddySignupView (and thus executing reverse), Django cannot find the URL.
You should use reverse_lazy instead: https://docs.djangoproject.com/en/1.11/ref/urlresolvers/#reverse-lazy
In your views.py file:
from django.core.urlresolvers import reverse_lazy
class BuddySignupView(SignupView):
template_name = 'buddy/buddy_create.html'
success_url = reverse_lazy('final') # profile specific success url
reverse_lazy only reverse the URL name at "runtime" (when Django actually needs the value) instead of "import time" when everything may not be available yet.

This error is coming because in any template file you are accecsing url(thank-you or signup) in wrong format. make sure about this url in html.

Related

Reverse and HttpResponseRedirect don't work with DefaultRouter

I need to send back response with product details, so I use HttpResponseRedirect and reverse. It requires the app_name:name, so I tried something like below, but I get error:
django.urls.exceptions.NoReverseMatch: Reverse for 'product' not found. 'ProductViewSet' is not a valid view function or pattern name.
This is my view:
#api_view(['POST'])
#permission_classes([IsAuthenticated])
def bump(request, pk):
product = get_object_or_404(Product, id=pk)
product.bumps.add(request.user)
return HttpResponseRedirect(reverse('products:product', args=[pk]))
This is my urls:
app_name = 'products'
router = DefaultRouter()
router.register(r'', ProductViewSet)
urlpatterns = [
path('', include(router.urls), name='product'),
]
What is wrong in this code? I use the correct app_name and name.
What is wrong in this code? I use the correct app_name and name.
The path you use does not link to a view: it is a path that contains a lot of subpaths, all generated by the DefaultRouter.
You are using a router, this means that it will create different paths that will each have a specific name. These are documented in the documentation for the DefaultRouter [drf-doc].
You thus can visit this with:
from django.shortcuts import redirect
#api_view(['POST'])
#permission_classes([IsAuthenticated])
def bump(request, pk):
product = get_object_or_404(Product, pk=pk)
product.bumps.add(request.user)
return redirect('products:product-detail', pk)

Django "NoReverseMatch: Reverse for 'ads.views.AdListView' not found" while doing Test

I implemented some tests to check the status code of some pages, but this one with the reverse function throws me the error: django.urls.exceptions.NoReverseMatch: Reverse for 'ads.views.AdListView' not found. 'ads.views.AdListView' is not a valid view function or pattern name.
Reading the documentation and some answers on Stack Overflow I'm supposed to use either the view function name or the pattern name inside the parenthesis of the reverse function, but none of them seems to work.
Here's my code:
ads/tests/test_urls.py
from django.test import TestCase
from django.urls import reverse
class SimpleTests(TestCase):
def test_detail_view_url_by_name(self):
resp = self.client.get(reverse('ad_detail'))
# I've also tried: resp = self.client.get(reverse('ads/ad_detail'))
self.assertEqual(resp.status_code, 200)
...
ads\urls.py
from django.urls import path, reverse_lazy
from . import views
app_name='ads'
urlpatterns = [
path('', views.AdListView.as_view(), name='all'),
path('ad/<int:pk>', views.AdDetailView.as_view(), name='ad_detail'),
...
]
mysite/urls.py
from django.urls import path, include
urlpatterns = [
path('', include('home.urls')), # Change to ads.urls
path('ads/', include('ads.urls')),
...
]
ads/views.py
class AdDetailView(OwnerDetailView):
model = Ad
template_name = 'ads/ad_detail.html'
def get(self, request, pk) :
retrieved_ad = Ad.objects.get(id=pk)
comments = Comment.objects.filter(ad=retrieved_ad).order_by('-updated_at')
comment_form = CommentForm()
context = { 'ad' : retrieved_ad, 'comments': comments, 'comment_form': comment_form }
return render(request, self.template_name, context)
Any idea of what is causing the problem?
Since you use an app_name=… in your urls.py, you need to specify this as a namespace in the name of the view, so ads:ad_detail, and specify a primary key:
resp = self.client.get(reverse('ads:ad_detail', kwargs={'pk': 42}))
So here we visit the URL where 42 is used as value for the pk URL parameter.

Django - URL not found using generic views

I am writing a basic Events app which contains of two modules(apps) so far : users and events.
I am using Django 2.1 with Python 3.6 on Ubuntu 16.04
So far, I've been able to handle users, but on events, I can't use Update, Detail and Delete generic views. All of them return 404.
My views.py:
class EventListView(ListView):
model = EventModel
template_name = 'event_list.html'
queryset = EventModel.objects.order_by('start_date_time')
class EventUpdateView(UpdateView):
model = EventModel
fields = ['event_type','start_date_time'
]
template_name = 'event_update.html'
class EventDeleteView(DeleteView):
model = EventModel
template_name = 'event_delete.html'
success_url = reverse_lazy('event_list')
class EventDetailView(DetailView):
model = EventModel
template_name = 'event_detail.html'
My urls.py (in project folder):
urlpatterns = [
path('', include('pages.urls')),
path('admin/', admin.site.urls),
path('users/', include('users.urls')),
path('users/', include('django.contrib.auth.urls')),
path('events/', include('events.urls')),
]
My urls.py (in events app):
urlpatterns = [
path('', views.EventListView.as_view(), name='event_list'),
path('<int:id>', views.EventDetailView.as_view(), name='event_detail'),
path('<int:id>/edit/', views.EventUpdateView.as_view(), name='event_update'),
path('<int:id>/delete/', views.EventDeleteView.as_view(), name='event_delete'),
]
What am I doing wrong? I've been searching the whole day and still have no idea how this might be wrong.
Note that the first line works (EventListView) but the other lines don't. By the way, I am using the book Django for Beginners. Most of the code here is identical to the code in the book.
Update
I don't use namespace in this application, the rest of urls.py is only some basic imports :
from django.urls import path
from . import views
The urls.py for the Project is like above, except it has include and admin as well.
The examples of URLs giving 404 error:
http://127.0.0.1:8000/events/1/
http://127.0.0.1:8000/events/1/edit/
PS I thought edit and delete give me 404, but actually the error is :
ImproperlyConfigured at /events/1/edit/
EventUpdateView is missing a QuerySet. Define EventUpdateView.model, EventUpdateView.queryset, or override EventUpdateView.get_queryset().)
In short: you defined a models (with s) attribute, but it should be model (without s).
Well the error actually already explains the problem:
ImproperlyConfigured at /events/1/edit/ EventUpdateView is missing a QuerySet.
Define EventUpdateView.model, EventUpdateView.queryset,
or override EventUpdateView.get_queryset().)
In your EventUpdateView you did not specify a model attribute, you wrote models, and for Django that is an entirely different attribute. So you should rename it to:
class EventListView(ListView):
model = EventModel
template_name = 'event_list.html'
queryset = EventModel.objects.order_by('start_date_time')
class EventUpdateView(UpdateView):
model = EventModel
fields = ['event_type','start_date_time'
]
template_name = 'event_update.html'
class EventDeleteView(DeleteView):
model = EventModel
template_name = 'event_delete.html'
success_url = reverse_lazy('event_list')
class EventDetailView(DetailView):
model = EventModel
template_name = 'event_detail.html'
For the EventListView, that did not matter, since you also defined a queryset attribute, and so Django took that one, but I would update it anyway.
Furthermore in the urls.py, you need to specify a pk parameter by default:
urlpatterns = [
path('', views.EventListView.as_view(), name='event_list'),
path('<int:pk>', views.EventDetailView.as_view(), name='event_detail'),
path('<int:pk>/edit/', views.EventUpdateView.as_view(), name='event_update'),
path('<int:pk>/delete/', views.EventDeleteView.as_view(), name='event_delete'),
]
Finally in the template you wrote something like:
{% url 'event_update' event.id %}
But apparently there was no event identifier, as a result the event.id is the string_if_invalid (by default the empty string), which is not an integer (well at least not if you did not specify that), and hence it can not find a relevant URL. After some discussion, it turned out that the correct identifier was object, so the correct url is something like:
{% url 'event_update' pk=object.id %}
The same of course should happen with other {% url ... %} calls.

Passing two arguments through URL

I have this link in my template:
See More
Here are my app urls:
from django.conf.urls import url
from listings import views
app_name = 'listings'
urlpatterns = [
url(r'^$',views.UniversityListView.as_view(),name='universities'),
url(r'^(?P<l_slug>[-\w]+)$',views.ListingView.as_view(),name='listing_detail'),
]
And here is my view associated with it:
class UniversityHomePageView(ListView):
model = Listing
context_object_name = 'listing'
template_name_suffix = '_university_homepage'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['university'] = University.objects.all()
context['company'] = Company.objects.all()
return context
I want this link to go to the the listings page however it is giving me an error:
NoReverseMatch at /tu/
Reverse for 'listing_detail' with keyword arguments '{'name_initials': '', 'l_slug': 'stafford-apartments'}' not found. 1 pattern(s) tried: ['(?P<name_initials>\\w+)/(?P<l_slug>[-\\w]+)$']
I am not really sure what to do. I think I need to be passing two variables to the view but if what I am doing isn't correct then I am a little lost on what to do, I have read the docs but don't quite no what to do still.
Using Django 1.11.

How to convert a Django ListView to work on the admin site?

I have a list view (for the admin site) that uses a template as follows:
class UserImageListPendingView(ListView):
model = UserImage
queryset = UserImage.objects.filter(status=ImageBase.PENDING)
template_name = 'userimage_list_pending.html'
context_object_name = 'userimage_list'
paginate_by = 5
#method_decorator(staff_member_required)
def dispatch(self, *args, **kwargs):
return super(UserImageListPendingView, self).dispatch(*args, **kwargs)
Although this works there are problems with putting the URL in urls.py:
urlpatterns = [
url(r'^admin/app/pendinguserimages/?$', login_required(
UserImageListPendingView.as_view()),
name='pendinguserimages'),
...
]
...as this stops the redirection working properly.
I did try to define the URL through admin.py:
def get_admin_urls(urls):
def get_urls():
return patterns('',
url(r'^app/pendinguserimages/?$',
UserImageListPendingView.as_view(), name='pendinguserimages'),
url(r'^app/checkuserimage/(?P<pk>[0-9]+)/?$',
userimage_check, name='checkuserimage'),
...
) + urls
return get_urls
admin_urls = get_admin_urls(admin.site.get_urls())
admin.site.get_urls = admin_urls
... but there was an error when reversing the checkuserimage URL.
How would I go about converting this view to fit in better with the admin site, but still use the template?
I didn't need to rewrite the ListView afterall. After defining the URLs in admin.py instead of in urls.py, all I needed to do was put "admin:" in front of the name when reversing the URL in the template, as follows:
check

Categories