Max Vallee
Max Vallee

Reputation: 468

Page not found (404) - No availability found matching the query

I'm getting a Page not found (404) on calling the Update and Delete views in my template.

My models are in such a way that multiple Staff can have multiple Availability entries. So I created a view to list the availability entries of each staff and I thought it would make sense to use a URL pattern that uses both the staff's pk and the availability entry's pk in order to delete or update the specific availability entries of a staff.

Example: To edit Staff #2's availability entry #4: http://127.0.0.1:8000/staff/2/availability/4/edit

Any clue why I'm getting this error?

I did some research and I'm wondering if I have to override the get_object method in the AvailabilityUpdateView and AvailabilityDeleteView?

urls.py

    path('staff/availability/new/', views.AvailabilityCreateView.as_view(), name='availability_new'),
    path('staff/<int:pk>/availability/', views.AvailabilityListView.as_view(), name='availability_list'),
    path('staff/<int:pk>/availability/<int:pk_alt>/edit/', views.AvailabilityUpdateView.as_view(), name='availability_edit'),
    path('staff/<int:pk>/availability/<int:pk_alt>/delete/', views.AvailabilityDeleteView.as_view(), name='availability_delete'),

Template

<a href="{% url 'availability_edit' pk_alt=availability.pk pk=availability.staff.pk %}">Edit</a> |
<a href="{% url 'availability_delete' pk_alt=availability.pk pk=availability.staff.pk %}">Delete</a>

Views

class AvailabilityUpdateView(UpdateView):
    template_name = 'crm/availability_form.html'
    form_class = AvailabilityForm
    model = Availability

class AvailabilityDeleteView(UpdateView):
    template_name = 'crm/availability_confirm_delete.html'
    model = Availability
    success_url = reverse_lazy('staff_list')

Upvotes: 0

Views: 92

Answers (1)

Pedram
Pedram

Reputation: 3920

The problem here is that, by default, django looks for a pk kwarg in your url to get the object, but you are sending it pk_alt as the availability's pk; simply change the pk_url_kwarg in your views:

class AvailabilityUpdateView(UpdateView):
    template_name = 'crm/availability_form.html'
    form_class = AvailabilityForm
    model = Availability
    pk_url_kwarg = 'pk_alt'

class AvailabilityDeleteView(DeleteView):  # <-- shouldn't it be DeleteView?
    template_name = 'crm/availability_confirm_delete.html'
    model = Availability
    success_url = reverse_lazy('staff_list')
    pk_url_kwarg = 'pk_alt'

Although in your case, it seems like you want to prevent staffs from editing other staff's availability, so it's better to override the get_object method to have control over that:

class AvailabilityUpdateView(UpdateView):
    template_name = 'crm/availability_form.html'
    form_class = AvailabilityForm
    model = Availability

    def get_object(self):
        return Availability.objects.get_object_or_404(pk=self.request.GET.get('pk_alt'), staff_id=self.request.GET.get('pk'))  # or request.POST

class AvailabilityDeleteView(DeleteView):  # <-- shouldn't it be DeleteView?
    template_name = 'crm/availability_confirm_delete.html'
    model = Availability
    success_url = reverse_lazy('staff_list')

    def get_object(self):
        return Availability.objects.get_object_or_404(pk=self.request.GET.get('pk_alt'), staff_id=self.request.GET.get('pk'))  # or request.POST

Upvotes: 2

Related Questions