0

I'm creating a Django project, and I've just implemented the functions for creating, editing, listing, and deleting an instance (object) through the front-end. See below:

The view to create an instance(add_category.py):

def add_category(request):
    template_name = 'tasks/add_category.html'
    context = {}
    if request.method == 'POST':
        form = CategoryForm(request.POST)
        if form.is_valid():
            f = form.save(commit=False)
            f.owner = request.user
            f.save()
            messages.success(request, 'Categoria adicionada com sucesso')
    form = CategoryForm()
    context['form'] = form
    return render(request, template_name, context)

The template add_category.html:

{% extends 'base.html' %}

{% load widget_tweaks}

{% block title %}
Adicionar Categoria - {{ block.super }}
{% endblock title %}
    

{% block body %}


    <div class="container">
        <h1>Categoria</h1>
        {% include 'partials/messages.html' %}
        <div class="row">
            <div class="col-md-12">
                <form action="." method="post">
                    {% csrf_token %}
                        <div class="form-group">              
                            <label for="{{ form.name.id_for_label }}">Nome</label>
                            {{ form.name }}                                                  
                        </div>
                        <div class="form-group">
                            <label for="{{ form.description.id_for_label }}">Descrição</label>
                            {{ form.description}}                   
                        </div>
                    <button class="btn btn-lg btn-primary btn-block mt-5" type="submit" >Salvar</button>
                </form>
            </div>
        </div>
    </div>
    
{% endblock body %}
    

The Url's:

from django.urls import path
from . import views

app_name = 'tasks'

urlpatterns = [
    path('categorias/', views.list_categories, name='list_categories'),
    path('categorias/adicionar/', views.add_category, name = 'add_category' ),
    path('categorias/editar/<int:id_category>', views.edit_category, name = 'edit_category' ),
    path('categorias/excluir/<int:id_category>', views.delete_category, name = 'delete_category' ),
]

so far it's working normally. See it: The template Save de object

This is the view of the instances list:

def list_categories(request):
    template_name = 'tasks/list_categories.html'
    categories = Category.objects.filter(owner=request.user)
    context = {
        'categories': categories
    }
    return render(request, template_name, context)

This is the template of the instances list:

{% extends 'base.html' %}

{% load widget_tweaks}

{% block title %}
Adicionar Categoria - {{ block.super }}
{% endblock title %}
    

{% block body %}

    <div class="container">
        <h1>Lista de categorias</h1>
        <div class="row">
            <div class="col-md-12">
                <table class="table">
                    <thead>
                        <tr>
                            <th scope="col">ID</th>
                            <th scope="col">Categorias</th>
                            <th scope="col">Ações</th>

                        </tr>
                    </thead>
                    <tbody>
                        {% for category in categories %}
                            <tr>
                                <th scope="row"> {{ category.id }} </th>
                                <td>{{ category.name }}</td>
                                <td>{{ category.description }}</td>
                                <td>
                                    <a href="{% url 'tasks:edit_category' category.id %}" class="btn btn-primary btn-sm">Editar</a>
                                    <a href="{% url 'tasks:delete_category' category.id %}" class="btn btn-danger btn-sm confirm-delete" data-bs-toggle="modal", data-bs-target="#confirmDeleteModal" id="deleteButton-{{ category.id }}">Excluir</a>
                                </td>
                            </tr>
                        {% endfor %}
                          
                    </tbody>
                    </table>
            </div>
        </div>
        {% include 'tasks/confirm_delete_modal.html' %}
    </div>
    

{% endblock body %}

It's working normally. See it: Objects List

When i click to edit it redirect to the add_category.html template, and load the instance using an id object to edit, see the view:

def edit_category(request, id_category):
    template_name = 'tasks/add_category.html'
    category = Category.objects.get(id=id_category, owner=request.user) 
    context = {}
    if request.method == 'POST':
        form = CategoryForm(request.POST, instance=category)
        if form.is_valid():
            form.save()
            messages.success(request, 'Categoria editada com sucesso')
            return redirect('tasks:list_categories')
    form = CategoryForm(instance=category)
    context['form'] = form
    return render(request, template_name, context)

This is the URL:

from django.urls import path
from . import views

app_name = 'tasks'

urlpatterns = [
    path('categorias/', views.list_categories, name='list_categories'),
    path('categorias/adicionar/', views.add_category, name = 'add_category' ),
    path('categorias/editar/<int:id_category>', views.edit_category, name = 'edit_category' ), # Here is the edit function URL.
    path('categorias/excluir/<int:id_category>', views.delete_category, name = 'delete_category' ),
    path('adicionar/', views.add_task, name='add_task'),
]

If the id object is 65, it redirect to the URL "...tarefas/categorias/editar/65", and loads all data that was saved. See the image: Edit function URL image

But when i save it, i receive an exception 404, See the Image: POST ERROR 404

where did i wrong?

I tried other solutions that generated other errors.

1 Answers1

0

The problem comes from your action="." in your add_category.html page. As the form is sent, it tries to redirect you to tarefas/categorias/excluir/ (note that there is no number at the end). Since your urls.py do not include tarefas/categorias/excluir/ (without any integer at the end), an error is raised.

In order to solve your problem, you can either

  • modify your add_category.html's action to redirect to another page, say for example action="#" if you want to be redirected to the current page.
  • add path('tarefas/categorias/excluir/', ...) to your URLs.

More has been discussed about relative URLs here.

Hope this helps !