Reputation: 468
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
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