Django - Reverse for 'index' not found. 'index' is not a valid view function or pattern name - django

I am new to Django.
I have been working based on the template from Mozilla: https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website
I have created a project called 'debtSettler'. And it has an app called 'home'.
I have the following url mappings:
./debtSettler/debtSettler/urls.py:
urlpatterns = [
path('home/', include('home.urls')),
path('admin/', admin.site.urls),
path('', RedirectView.as_view(url='home/')),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
./debtSettler/home/urls.py:
app_name = 'home'
urlpatterns = [
path('', views.index, name='index'),
path('clubs/', views.ClubListView.as_view(), name='clubs'),
]
And views:
./debtSettler/home/views.py:
from django.http import HttpResponse, HttpResponseRedirect
def index(request):
num_clubs = Club.objects.all().count()
# The 'all()' is implied by default.
num_members = Member.objects.count()
context = {
'num_clubs': num_clubs,
'num_members': num_members,
}
# Render the HTML template index.html with the data in the context variable
return render(request, 'index.html', context=context)
class ClubListView(generic.ListView):
model = Club
def get_context_data(self, **kwargs):
# Call the base implementation first to get the context
context = super(ClubListView, self).get_context_data(**kwargs)
# Create any data and add it to the context
context['some_data'] = 'This is just some data'
return context
In the template, I have two urls that give the error:
Home
All clubs
Reverse for 'index' not found. 'index' is not a valid view function or pattern name.
If I add the my_app:my_view, it works as expected:
Home
All clubs
but I plan to do more of the url mapping further in the app so I want to understand what I am doing wrong with the url.
It seems to me like I am doing things very similar to the tutorial.

try to add "home:" before'index'
try this:
Home
All clubs
And you should add namespace
urlpatterns = [
path('home/', include('home.urls','home'),namespace = 'home'),
path('admin/', admin.site.urls),
path('', RedirectView.as_view(url='home/')),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

You used an app_name, so then the view names are "namespace" with:
Home
All clubs

Related

url is showing in page not found error in django?

I created an endpoint and registered it in urls.py. When I try to hit the endpoint I get a 404 error but on the 404 page the url is shown as one of the patterns django tried to match. Stumped.
api.py
class UpdateLast(viewsets.GenericViewSet, UpdateModelMixin):
def get(self):
return XYZModel.objects.all()
def partial_update(self, request, *args, **kwargs):
if request.user.is_superuser:
with transaction.atomic():
for key, value in request.data:
if key == 'tic':
XYZModel.objects.filter(ticker=request.data['tic']).filter(trail=True).update(
last_high=Case(
When(
LessThan(F('last_high'),
request.data['high']),
then=Value(request.data['high'])),
default=F('last_high')
)
)
urls.py (this is inside the app)
router = routers.DefaultRouter()
router.register('api/dsetting', DViewSet, 'dsetting')
router.register('api/update-last-high', UpdateLast, 'update-last-high')
urlpatterns = [
path('', include(router.urls))
]
urls.py (main)
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('my_app.urls')),
When I hit the end-point api/update-last-high I get a 404 page.
On that page the exact end-point is shown as a pattern that django tried to match.
^api/update-last-high/(?P[^/.]+)/$ [name='update-last-high-detail']
^api/update-last-high/(?P[^/.]+).(?P[a-z0-9]+)/?$ [name='update-last-high-detail']
from rest_framework import routers
from . import views
from django.urls import path, include
router = routers.DefaultRouter()
router.register('api/dsetting', DViewSet, 'dsetting')
router.register('api/update-last-high', UpdateLast, 'update-last-high')
# you forgot to include the router.urls
urlpatterns = [
path('', include(router.urls))
]

Django secondary admin site links to main admin site

I'm trying to add a secondary admin site and it's working correctly except that any links are pointing to the main admin site. Not sure how to get around this.
If I visit /dispatch/admin/ the model Run is visible but when I click the link it directs me to /admin/dispatch/run/ instead of /dispatch/admin/dispatch/run/.
Django==3.2.7
class DispatchAdminSite(admin.AdminSite):
pass
class DispatchRunAdmin(RunAdmin):
def get_queryset(self, request):
return (
super().get_queryset(request)
.filter_today_or_future()
)
def get_readonly_fields(self, request, obj=None):
return [f.name for f in self.model._meta.fields]
dispatch_admin_site = DispatchAdminSite(name='Dispatch')
dispatch_admin_site.register(models.Run, DispatchRunAdmin)
dispatch/urls.py
app_name = 'dispatch'
urlpatterns = [
path('admin/', admin.dispatch_admin_site.urls),
]
project/urls.py
urlpatterns = [
path('dispatch/', include('dispatch.urls')),
path('admin/', admin.site.urls),
]
For whatever reason the custom admin can't be added using include it has to be a top level URL in your project.
# project/urls.py
from django.contrib import admin
from dispatch.admin import dispatch_admin_site
urlpatterns = [
path('dispatch-admin/', dispatch_admin_site.urls),
path('admin/', admin.site.urls),
]

How to include other app's urls.py in get_absolute_url: reverse() django?

In app models.py, I am using get_absolute_url to reverse to a particular path using "name" that is in different app urls.py.
But of course I am getting error because the I have not created urls.py for that app as the urlpattern is already present in some other urls.py.
So is there any include(app.urls) type functionality that I can use in reverse?
#app: A - urls.py
urlpatterns = [
path('post/<int:pk>/', PostDetailView.as_view(), name = 'post-detail'),
...
]
#app: B - models.py
def get_absolute_url(self):
return reverse('post-detail',kwargs = {'post_id.id':self.post_id.id})
in your main urls.py file you have to add all your app urls as follows and call it in your get absolute method. You are defining this method to that particular model only, and is linked to the instance by self.
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('your_app.urls')),
]
also you can modify your get absolute method as
def get_absolute_url(self):
return reverse('post-detail',kwargs = {"pk": self.pk)

Force URL to match a view with re_path

I've a view that should be called when entering:
1) stickersgallit.pe/ordenes/ingresos or
2) http://127.0.0.1:8000/ordenes/ingresos (locally).
However, it is entering and activating other view AddProduct, as it is guessing ordenes is c_slug and ingresos is product_slug, when they aren't:
path('<slug:c_slug>/<slug:product_slug>', views.AddProduct, name='AddProduct'),
Questions:
a) How to force /ordenes/ingresos to activate my classOrdersListView (in order/views/class OrdersListView(ListView))?
b) Or How can I limit what the URL views.AddProduct considers as c_slug and product_slug?
IMPORTANT:
In urls.py project level, order.urls is already on top of shop.urls but I keep getting:
ValueError at /ordenes/ingresos The view shop.views.AddProduct didn't
return an HttpResponse object. It returned None instead.
urlpatterns = [
path('admin/', admin.site.urls),
path('ordenes/', include('order.urls')),
path('', include('shop.urls')),
path('carrito_de_compras/', include('cart.urls')),
path('marketing/', include('marketing.urls')),
path('registrarse/', views.signupView, name = 'signup'),
path('ingresar/', views.signinView, name = 'signin'),
path('salir/', views.signoutView, name = 'signout'),
path('province/', views.get_province, name = 'province'),
]
Proyect urls.py:
from django.contrib import admin
from django.urls import path, include, re_path
from shop import views
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
re_path('^/ordenes/', include('order.urls')),
path('', include('shop.urls')),
path('carrito_de_compras/', include('cart.urls')),
path('marketing/', include('marketing.urls')),
path('registrarse/', views.signupView, name = 'signup'),
path('ingresar/', views.signinView, name = 'signin'),
path('salir/', views.signoutView, name = 'signout'),
path('province/', views.get_province, name = 'province')
]
shop URLs:
from django.contrib import admin
from django.urls import path, re_path
from . import views
app_name = 'shop'
urlpatterns = [
path('admin', admin.site.urls),
path('', views.allCat, name='allCat'),
path('packs/', views.PacksPage, name='PacksPage'), #Todos los packs
path('catalogo', views.CatalogoListView.as_view(), name='catalogo'), #Todos los productos unitarios
path('muestras/', views.SamplePackPage, name='SamplePackPage'), #Todas las muestras
path('province/', views.get_province, name='province'),
path('district/', views.get_district, name='district'),
path('quienes-somos/', views.quienes_somos, name='quienes_somos'),
path('como-comprar/', views.como_comprar, name='como_comprar'),
path('contactanos/', views.contactanos, name='contactanos'),
path('preguntas-frecuentes/', views.preguntas_frecuentes, name='preguntas_frecuentes'),
path('legales/privacidad', views.legales_privacidad, name='legales_privacidad'),
path('legales/terminos', views.legales_terminos, name='legales_terminos'),
path('muestras/<slug:sample_slug>/medida-y-cantidad', views.StepOneView_Sample.as_view(), name='SampleDetail'),
path('muestras/<slug:sample_slug>/subir-arte', views.StepTwoView_Sample.as_view(), name='UploadArt'),
path('<slug:c_slug>/<slug:product_slug>/medida-y-cantidad', views.StepOneView.as_view(), name='ProdDetail'),
path('<slug:c_slug>/<slug:product_slug>/subir-arte', views.StepTwoView.as_view(), name='UploadArt'),
path('<slug:c_slug>/<slug:product_slug>', views.AddProduct, name='AddProduct'),
path('stickers-por-unidad/', views.AddUnitaryProduct, name='AddUnitaryProduct'),
path('<slug:c_slug>', views.ProdCatDetail, name='ProdCatDetail'),
path('make_review/', views.make_review_view, name='make_review_view'),
path('prices/', views.prices, name='prices'),
path('email_confirmation_needed/', views.email_confirmation_needed, name='email_confirmation_needed'),
re_path(r'^confirmacion-de-correo-electronico/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
views.activate, name='activate')
]
order URLS:
from django.urls import path
from . import views
app_name = 'order'
urlpatterns = [
# path('thanks/<int:order_id>/', views.thanks, name = 'thanks'),
path('/gracias_pago_con_tarjeta_de_credito/', views.thanks_credit_card, name='thanks_credit_card'),
path('/gracias_pago_con_deposito_en_efectivo/', views.thanks_deposit_payment, name='thanks_deposit_payment'),
path('/historial_de_compras/', views.orderHistory, name = 'order_history'),
path('/<int:order_id>/', views.viewOrder, name = 'order_detail'),
path('/ingresos/', views.OrdersListView.as_view(), name='ingresos'), #Todas las órdenes con filtro
]
a) Django will resolve URLs in the order they're presented in your urls.py files, so I'd assume your /ordenes/ URL is below, the easiest way is to put all the /ordenes/ urls before AddProduct, so when the URL doesn't match /ordenes/ingresos/ then it will continue down the array until it matches with AddProduct
b) You can limit the AddProduct view the same way you're limiting the /confirmacion-de-correo-electronico/ view, by using re_path instead of path and defining a regular expression that represents your slugs. Maybe they're all lowercase, maybe they don't contain certain symbols.
Adding to #PabloAlbonrnoz 's answer, I think your URL definations are wrong, you need to change like this:
# in root url
path('ordenes/', include('order.urls')),
# in order url
urlpatterns = [
# path('thanks/<int:order_id>/', views.thanks, name = 'thanks'),
path('gracias_pago_con_tarjeta_de_credito/', views.thanks_credit_card, name='thanks_credit_card'),
path('gracias_pago_con_deposito_en_efectivo/', views.thanks_deposit_payment, name='thanks_deposit_payment'),
path('historial_de_compras/', views.orderHistory, name = 'order_history'),
path('<int:order_id>/', views.viewOrder, name = 'order_detail'),
path('ingresos', views.OrdersListView.as_view(), name='ingresos'),
]
Basically I removed / which was at beginning of the URL definitions.
Probably I don't agree with the b section of Pablo's answer. I would say to handle it in the view or form. For example:
from django.http import Http404
class AddProduct(CreateView):
def post(self, request, *args, **kwargs);
slug = request.kwargs.get('c_slug')
if not slug in ['paper', "vinyl", "laminated"]:
return Http404('option not found')
return super().post(request, *args, **kwargs)
Or if you don't want to have it like this, then you can follow Pablo's suggestion, then the url will be:
re_path(r'^(paper|vinyl|laminated)/(?P<product_slug>[\w-]+)$', views.AddProduct, name='AddProduct')

Reverse for 'index' not found. 'index' is not a valid view function or pattern name

I have a simple return HttpResponseRedirect(reverse('index')) where 'index' is the name of the view. on running the server the index view is correctly displayed but gives out this error "NoReverseMatch at /vehicle_movement/checkinview"on redirecting.
I was working on django 1.1 for the same project but switched to django 2.2 later. Redirect was working fine with url django 1.1 but gives this error with path django 2.2. Another change that i have done is earlier in 1.1 project the index view url was written in the main url.py but now it is written in the apps urls.py.
This is views.py
def index(request):
return render(request,'vehicle_movement/index.html',{})
def CheckinView(request):
if request.method == "POST":
checkin_form = CheckinForm(data = request.POST)
if checkin_form.is_valid():
checkin_form.save()
return HttpResponseRedirect(reverse('index'))
else:
HttpResponse("Error")
else:
checkin_form = CheckinForm()
return render(request,'vehicle_movement/checkin.html',{'checkin_form':checkin_form})
This is the Main urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(('vehicle_movement.urls','vehicle_movement'),namespace = 'vehicle_movement')),
]
This is app urls.py
app_name = 'vehicle_movement'
urlpatterns = [
path('', views.index, name='index'),
path('index', views.index, name='index'),
]
This is the structure
Warehouse
-Warehouse
-init.py
-settings.py
-urls.py
-static
-templates
-vehicle_movement
-urls.py
-views.py
The TEMPLATES_DIR
TEMPLATES_DIR = os.path.join(BASE_DIR,'templates')
``
You've namespaced your app urls, so you need to use that namespace when reversing them:
reverse('vehicle_movement:index')
But you've also got two paths with the same name in your app urls, which will cause conflicts, if not an error. Delete one of them.
Check name="htmlfilename" in app urls is correct or not.