Omar Gonzales
Omar Gonzales

Reputation: 4008

Django: cannot redirect to UpdateView after item is deleted

I'm creating a view just for deleting ListItems that correspond to a List objects, through a ForeignKey.

I can successfully delete the ListItem, but I cannot redirect to the original template.

def full_remove_listitem(request, listitem_id):
    list_item = ListItem.objects.get(id=listitem_id)
    list_item.delete()
    lista_id = list_item.lista.id
    return redirect('lists:list_details lista_id')

I get:

NoReverseMatch at /listas/borrar-producto-de-lista/29/
Reverse for 'list_details lista_id' not found. 'list_details lista_id' is not a valid view function or pattern name.

I've also tried:

return reverse('lists:list_details', kwargs={'lista_id': lista_id})

But I get:

AttributeError at /listas/borrar-producto-de-lista/30/ 'str' object has no attribute 'get'

Urls.py:

app_name = "lists"

urlpatterns = [
    path('', views.ListFormView.as_view(), name='my_lists'),
    path('agregar-producto/', views.add_product_to_list, name='add_product_to_list'),
    path('mis-listas/', views.update_lists_count, name='update_lists_count'),
    path('lista-detalles/<int:lista_id>/', views.ListDetailsFormView.as_view(), name='list_details'),
    path('escuelas-csv/', views.schools_upload, name="schools_upload"),
    path('borrar-producto-de-lista/<int:listitem_id>/', views.full_remove_listitem, name='full_remove_listitem'),
    path('borrar-lista/<int:lista_id>/', views.full_remove_list, name='full_remove_list'),
    path('borrar-escuela/<int:school_id>/', views.full_remove_school, name='full_remove_school'),
]

HTML:

<div class="row">
    {% for list_item in list_items %}
        {% if forloop.counter0|divisibleby:3 and not forloop.first %}<div class="w-100"></div>{% endif %}
        <div class="card margin-right3" style="width: 14rem;">
            <div class="card-body">
              <h5 class="card-title">{{ list_item.product.short_name }}</h5>
              <p class="card-title">$ {{ list_item.product.price }}</p>
              <p class="card-text">{{ list_item.description }}</p>
              <a href="{% url 'lists:full_remove_listitem' list_item.id %}" class="custom_icon"><i
                class="fas fa-trash-alt custom_icon"></i></a>
            </div>
        </div> 
    {% endfor %}

views.py: View where I want to redirect:

class ListDetailsFormView(LoginRequiredMixin, UpdateView):
    model = List
    form_class = ListForm
    context_object_name = 'lista'
    pk_url_kwarg  = 'lista_id'
    template_name = "scolarte/listas/lista-detalles.html"

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        list_items = ListItem.objects.filter(lista=self.object)
        context['list_items'] = list_items
        list_total = 0
        for list_item in list_items:
            list_total += Decimal(list_item.sub_total())
        context['list_total'] = list_total
        return context

    def form_valid(self, form):
        #form.instance.name = self.request.name
        return super().form_valid(form)

    def get_success_url(self):
        return reverse('lists:list_details', kwargs={'lista_id': self.object.pk})

models.py:

class ListItem(models.Model):
    lista = models.ForeignKey(List, on_delete=models.CASCADE)
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    comment = models.CharField(max_length=100, blank=True, null=True, default='')
    uploaded_at = models.DateTimeField(auto_now_add=True)
    step_two_complete = models.BooleanField(default=False)

    def sub_total(self):
        return int(self.product.price)

Upvotes: 0

Views: 65

Answers (1)

bdoubleu
bdoubleu

Reputation: 6107

If you take a look at the second example in the redirect() documentation you'll see that the first argument should be the view name then the id can be passed as a keyword argument.

def full_remove_listitem(request, listitem_id):
    list_item = ListItem.objects.get(id=listitem_id)
    list_item.delete()
    lista_id = list_item.lista.id
    return redirect('lists:list_details', lista_id=lista_id)

Upvotes: 1

Related Questions