Django delete record using modal - django

I'm new in Django and i like to implement a Modal to delete records. The problem is a funny error in the modal form because is expecting a parameter. The modal link has this
but I don't know how add the right parameter.
This is my List in html
<table id="tablaAlmacenes" class="table table-bordered table-striped">
<thead>
<tr>
<th>Almacén</th>
<th>Detalles</th>
<th></th>
</tr>
</thead>
<tbody>
{% for almacen in object_list %}
<tr>
<td>{{ almacen.almacen }}</td>
<td>{{ almacen.descripcion }}</td>
<td>
<div>
Detalles
<a a href="" class="btn btn-link text-primary">Editar</a>
<a class="btn btn-link deleteAlmacen" data-id="{{ almacen.id}}"><span class="fas fa-trash text-danger"></a>
</div>
</td>
</tr>
{% endfor %}
</tbody>
<tfoot>
<tr>
<th>Almacén</th>
<th>Detalles</th>
<th></th>
</tr>
</tfoot>
</table>
this is my url.py
urlpatterns = [
path('',include('polls.urls'),name='home'),
path('admin/', admin.site.urls),
# path('contact/',views.contact, name='contacto')
path('almacenes/', AlmacenesListView.as_view(), name='almacenes'),
path('almacenes/nuevo', AlmacenesCreateView.as_view(), name='crear_almacen'),
path('almacenes/<int:id>/remove/', AlmacenesDeleteView.as_view(), name='eliminar_almacen')
]
This is my views.py
class AlmacenesListView(ListView):
model = Almacen
template_name = 'pages/index.html'
success_message = "Bien!!!!"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['title'] = "Lista de Almacenes"
print(reverse_lazy('almacenes'))
return context
class AlmacenesCreateView(SuccessMessageMixin, CreateView):
model = Almacen
form_class = AlmacenesForm
success_url = reverse_lazy('almacenes')
success_message = "Bien!!!!"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
return context
class AlmacenesDeleteView(DeleteView):
model = Almacen
success_url = reverse_lazy('almacenes')
and my modal code
<div class="modal fade" aria-modal="false" id="deleteAlmacenModal">
<div class="modal-dialog modal-dialog-centered modal-sm">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Confirmación</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Cerrar">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>¿Desea eliminar el Almacen?</p>
</div>
<div class="modal-footer justify-content-between">
<button type="button" class="btn btn-default" data-dismiss="modal">Cerrar</button>
<form action="{% url 'eliminar_almacen' (some parameter here but error) %}" method="POST">
{% csrf_token %}
<input type="hidden" name="id" id="almacen_id"/>
<button type="submit" class="btn btn-danger">Eliminar</button>
</form>
</div>
</div>
<!-- /.modal-content -->
</div>
<!-- /.modal-dialog -->
</div>
scrpt for modal
$(document).on('click','.deleteAlmacen',function(){
var id_almacen=$(this).attr('data-id');
$('#almacen_id').val(id_almacen);
$('#deleteAlmacenModal').modal('show');
});

So, if you are using bootstrap you don't need to trigger the modal with jquery but let bootstrap do the magic.
Your code should be something like that:
html:
<table id="tablaAlmacenes" class="table table-bordered table-striped">
<thead>
<tr>
<th>Almacén</th>
<th>Detalles</th>
<th></th>
</tr>
</thead>
<tbody>
{% for almacen in object_list %}
<tr>
<td>{{ almacen.almacen }}</td>
<td>{{ almacen.descripcion }}</td>
<td>
<div>
Detalles
<a a href="" class="btn btn-link text-primary">Editar</a>
<a class="btn btn-link" data-toggle="modal" data-target="#deleteAlmacenModal{{almacen.id}}""><span class="fas fa-trash text-danger"></a> <!-- data-toggle and data-target work in bootstrap4, in 5 is data-bs-target and data-bs-toggle -->
{% include 'yourtemplatefolder/modals/delete_almacen_modal.html' %} <!-- as best practice create another folder called modals and put there you modal.html files, as in this case and include them in your code -->
</div>
</td>
</tr>
{% endfor %}
</tbody>
<tfoot>
<tr>
<th>Almacén</th>
<th>Detalles</th>
<th></th>
</tr>
</tfoot>
</table>
Now, being the modal called inside the for loop, you can fix your modal like this:
delete_almacen_modal.html
<div class="modal fade" aria-modal="false" id="deleteAlmacenModal{{almacen.id}}">
<div class="modal-dialog modal-dialog-centered modal-sm">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Confirmación</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Cerrar">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>¿Desea eliminar el Almacen?</p>
</div>
<div class="modal-footer justify-content-between">
<button type="button" class="btn btn-default" data-dismiss="modal">Cerrar</button>
<form action="{% url 'eliminar_almacen' pk=almacen.id %}" method="POST">
{% csrf_token %}
<input type="hidden" name="id" id="almacen_id"/>
<button type="submit" class="btn btn-danger">Eliminar</button>
</form>
</div>
</div>
<!-- /.modal-content -->
</div>
<!-- /.modal-dialog -->
</div>
Now that should work.

Related

How to use a Bootstrap Modal to delete in Django?

Must I add to JavaScript section or not?
HTML
</head>
<body>
<div class="container-xl">
<div class="table-responsive">
<div class="table-wrapper">
<div class="table-title">
<div class="row">
<div class="col-sm-6">
<h2><b>Shipping</b></h2>
</div>
<div class="col-sm-6">
</i> <span>Add New Shipping</span>
<div class="col-sm-6">
<div class="search-box">
<div class="input-group">
<input type="text" id="search" class="form-control" placeholder="Search by Name">
<span class="input-group-addon"><i class="material-icons"></i></span>
</div>
</div>
</div>
</div>
</div>
</div>
<table class="table table-striped table-hover">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Destination</th>
<th>Date</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for shipping in shipping_info %}
<tr>
<td>{{ shipping.shipping_id }}</td>
<td>{{ shipping.driver_id.driver_fname }} {{ shipping.driver_id.driver_lname }}</td>
<td>{{ shipping.destination }}</td>
<td>{{ shipping.ship_date }}</td>
<td>
</i>
<i class="material-icons" data-toggle="tooltip" title="Delete"></i>
<a href="{% url 'view_shipping' shipping.shipping_id %}" class="" ><span class="material-icons">
visibility
</span></a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
HTML:
<!-- Delete Modal HTML -->
<form method="post" action="">
{% csrf_token %}
<div id="deleteEmployeeModal" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<form>
<div class="modal-header">
<h4 class="modal-title">Delete User</h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<div class="modal-body">
<p>Are you sure you want to delete these Records?</p>
<p class="text-warning"><small>This action cannot be undone.</small></p>
</div>
<div class="modal-footer">
<input type="button" class="btn btn-default" data-dismiss="modal" value="Cancel">
<input type="submit" class="btn btn-danger" value="Delete">
</div>
</form>
</div>
</div>
</div>
</form>
{% endblock %}
</body>
</html>
I can delete but it doesn't have modal so I added this but when I add it can't delete.
view
def delete_shipping(request,pk):
del_dri = shipping.objects.get(shipping_id=pk)
del_dri.delete()
return redirect('table_shipping')
The problem is a funny error in the modal form
Url
path("delete_shipping/<str:pk>",views.delete_shipping,name='delete_shipping'),
You're tried change input:
<div class="modal-footer">
<input type="button" class="btn btn-default" data-dismiss="modal" value="Cancel">
<input type="submit" class="btn btn-danger" value="Delete">
</div>
to:
<div class="modal-footer">
<input type="button" class="btn btn-default" data-dismiss="modal" value="Cancel">
<a hrfe= "{% url "delete_shipping" %}" class="btn btn-danger">Delete </a>
</div>
?

Django CreateView form in modal not show

I have a simple CRUD for a table named Clasificacion. The problem is I would like use a Modal for insert record, but actually I don't use the Django form, instead I declared a normal form with all the fields one by one, but I would like use the From, but is not posible for me show the form content, instead the modal shows empty with the ok button.This table has a model declared as:
class Clasificaciones(models.Model):
clasificacion=models.CharField(max_length=30)
detalles=models.CharField(max_length=1000)
This is How I declared the ListView and the CreateView
class ClasificacionesListView(ListView):
model = Clasificaciones
template_name = 'clasificacion/index.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['title'] = "Lista de clasificaciones"
return context
class ClasificacionesCreateView(SuccessMessageMixin, CreateView):
model = Clasificaciones
form_class = ClasificacionesForm
template_name = 'clasificacion/index.html'
success_url = reverse_lazy('clasificaciones')
success_message = "Insertado correctamente!!!!"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
return context
and this is the index.html with the modal. The modal is in other directory but not works if I put in the same index.html file
{% extends "starter.html" %}
{% block content %}
<div class="content-wrapper">
<section class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-sm-6">
<div class="pull-right">
<button type="button" class="btn btn-success" data-toggle="modal" data-target="#modalAddClasificacion">Nueva clasificación</button>
</div>
</div><!-- /.col -->
</div><!-- /.row -->
</div><!-- /.container-fluid -->
</section>
<section class="content">
<div class="content-fluid">
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">Clasificaciones</h3>
</div>
<div class="card-body">
<table id="tablaClasificaciones" class="table table-bordered table-striped">
<thead>
<tr>
<th>Clasificación</th>
<th>Detalles</th>
<th></th>
</tr>
</thead>
<tbody>
{% for clasificacion in object_list %}
<tr>
<td>{{ clasificacion.clasificacion }}</td>
<td>{{ clasificacion.detalles }}</td>
<td>
<div>
<!-- Detalles -->
Editar
<a class="btn btn-link" data-toggle="modal" data-target="#deleteClasificacionModal{{clasificacion.id}}"><span class="fas fa-trash text-danger"></a>
{% include 'clasificacion/modals/delete_modal.html' %}
</div>
</td>
</tr>
{% endfor %}
</tbody>
<tfoot>
<tr>
<th>Clasificación</th>
<th>Detalles</th>
<th></th>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
</div>
</div>
</section>
</div>
{% include 'clasificacion/modals/add_modal.html' %}
{% endblock %}
and the modal code, commented the inputs, this way works, but I would like use form
<div class="modal fade" id="modalAddClasificacion">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Adicionar clasificación</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Cerrar">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="row">
<form id="addclasificacion" method="POST">
{% csrf_token %}
<div class="row">
{% for field in form.visible_fields %}
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>{{ field.label }}</strong>
{{ field }}
</div>
</div>
{%endfor%}
<!-- <div class="col-12">
<div class="form-group">
<strong>Clasificación:</strong>
<input type="text" name="clasificacion" class="form-control" placeholder="Clasificación">
</div>
</div>
<div class="col-12">
<div class="form-group">
<strong>Detalles:</strong>
<textarea class="form-control" style="height:150px" name="detalles" placeholder="Detalles"></textarea>
</div>
</div> -->
<div class="col-xs-12 col-sm-12 col-md-12 text-center">
<button type="submit" class="btn btn-primary">Insertar</button>
</div>
</div>
</form>
</div>
</div>
</div>
<!-- /.modal-content -->
</div>
<!-- /.modal-dialog -->
</div>
It not works because I must add to context variable the form, in this case the Form to Categoria model. Also I must add to Create form, because I don't use a create template.
So this is the answer:
class ClasificacionesListView(ListView):
model = Clasificaciones
template_name = 'clasificacion/index.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['title'] = "Lista de clasificaciones"
context['form'] = ClasificacionesForm()#here the detail.
return context

The delete view doesn't erase the correspondent object

I'm developing the backend of my personal blog and I've create a view that delete a single tag of the post.
views.py
from django.shortcuts import get_object_or_404, redirect, render
from django.utils.text import slugify
from .forms import BlogTagForm
from .models import BlogTag
def deleteBlogTag(request, slug_tag):
if request.method == 'POST':
tag = BlogTag.objects.get(slug_tag=slug_tag)
tag.delete()
return redirect('tag_list')
models.py
from django.db import models
from django.urls import reverse
class BlogTag(models.Model):
tag_name = models.CharField(
'Tag',
max_length=50,
help_text="Every key concept must be not longer then 50 characters",
unique=True,
)
slug_tag = models.SlugField(
'Slug',
unique=True,
help_text="Slug is a field in autocomplete mode, but if you want you can modify its contents",
)
def __str__(self):
return self.tag_name
def get_absolute_url(self):
return reverse("single_blogtag", kwargs={"slug_tag": self.slug_tag})
class Meta:
ordering = ['tag_name']
urls.py
path("tags/", views.listTagAdmin, name='tag_list_admin'),
path("create-tag/", views.createBlogTag, name='create_tag'),
path("update-tag/<str:slug_tag>/", views.updateBlogTag, name='update_tag'),
path("delete-tag/<str:slug_tag>/", views.deleteBlogTag, name='delete_tag'),
tag_list.html
<table class="table table-striped">
<thead class="bg-secondary text-white">
<tr>
<th colspan="3"><h1 class="text-center"><strong>Tag List</strong></h1></th>
</tr>
<tr>
<th colspan="1">Tag</th>
<th colspan="1">Related Posts</th>
<th class="text-center" colspan="1">Actions</th>
</tr>
</thead>
<tbody>
{% for tag in tag_list %}
<tr>
<td colspan="1">{{ tag.tag_name }}</td>
<td colspan="1">{{ tag.tag_blogpost.count }}</td>
<td colspan="1">
<div class="row justify-content-md-center">
<a class="btn btn-success btn-sm mx-1" href="{% url 'update_tag' slug_tag=tag.slug_tag %}">Update</a>
<button class="btn btn-danger btn-sm mx-1" type="button" data-toggle="modal" data-target="#deleteModal">Delete</button>
<div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="deleteModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title text-center" id="deleteModalLabel">Delete Request</h2>
</div>
<div class="modal-body">
<h3>Are you sure to delete this tag?</h3>
<h1 class="py-4"><em><strong>{{ tag.tag_name }}</strong></em></h1>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary btn-sm" data-dismiss="modal">No, don't do this</button>
<form action="{% url 'delete_tag' slug_tag=tag.slug_tag %}" method="POST">
{% csrf_token %}
<button class="btn btn-danger btn-sm" type="submit" name="button">Yes, delete it</button>
</form>
</div>
</div>
</div>
</div>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
The problem is that it's not possible to delete every single objects of the list but only the first object. Even if I try to delete the last object I delete the first object instead of the last.
Where I've wrong?
All your modal forms are named the same, hence it will pick one. If it searches for a specific id, it will pick one. In order to solve this, you should give your modals different ids:
<tbody>
{% for tag in tag_list %}
<tr>
<td colspan="1">{{ tag.tag_name }}</td>
<td colspan="1">{{ tag.tag_blogpost.count }}</td>
<td colspan="1">
<div class="row justify-content-md-center">
<a class="btn btn-success btn-sm mx-1" href="{% url 'update_tag' slug_tag=tag.slug_tag %}">Update</a>
<button data-target="#deleteModal{{ tag.pk }}" class="btn btn-danger btn-sm mx-1" type="button" data-toggle="modal">Delete</button>
<div class="modal fade" id="deleteModal{{ tag.pk }}" tabindex="-1" role="dialog" aria-labelledby="deleteModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title text-center" id="deleteModalLabel">Delete Request</h2>
</div>
<div class="modal-body">
<h3>Are you sure to delete this tag?</h3>
<h1 class="py-4"><em><strong>{{ tag.tag_name }}</strong></em></h1>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary btn-sm" data-dismiss="modal">No, don't do this</button>
<form action="{% url 'delete_tag' slug_tag=tag.slug_tag %}" method="POST">
{% csrf_token %}
<button class="btn btn-danger btn-sm" type="submit" name="button">Yes, delete it</button>
</form>
</div>
</div>
</div>
</div>
</div>
</td>
</tr>
So here we added a suffix to the id of the <div class="modal fade" id="deleteModal{{ tag.pk }}" ...>, and used the same id in the <button target="#deleteModal{{ tag.pk }}" ...>.

How to create such a table with checkbox in django?

I want to have a table with a checkbox on each row with Django as shown in the image. My Django view.py, models.py and HTML file are mentioned below. How this can be done? Is there any built-in function in Django or what?
Table with check box
I have models file as:
class AppsDescription(db.Model):
aws_response = aws_list_conf_api_call()
CHOICES = [("yes", "YES"),
("no", "NO")]
OPTIONS = list()
for apps in aws_response:
OPTIONS.append(('{name1}'.format(name1=apps.lower()), '{name2}'.format(name2=apps)), )
name = db.CharField(max_length=256)
description = db.TextField()
plan_to_migrate = db.CharField(choices=CHOICES, max_length=256)
# app_names = MultiSelectField(choices=OPTIONS)
def __str__(self):
return self.name
My views.py as
def createapp(request):
# import ipdb; ipdb.set_trace()
form = DashboardForm()
if request.method == "POST":
form = DashboardForm(request.POST)
list_of_inputs = request.POST.getlist("inputs")
if form.is_valid:
form.save(commit=True)
return HttpResponseRedirect(reverse("aws:createapp"))
server = aws_server_list_conf()
return render(request, "createapp.html", {'server':server, 'form': form})
My html file as
<form method="POST">
{{form.as_p}}
<table>
<tr>
<th>Select</th>
<th>Agent ID</th>
<th>Configuration ID</th>
<th>Host Name</th>
<th>OS Name</th>
<th>OS Version</th>
<th>Source</th>
<th>Time of Creation</th>
<th>Type</th>
</tr>
{% for apps in server %}
<tr>
<td><input type="checkbox" name="" value=""></td>
{% for k,v in apps.items %}
<td>{{ v }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
{% csrf_token %}
<input type="submit" class="btn btn-info btn-lg" data-toggle="modal" data-target="#myModal" name="" value="submit">
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<div class="alert alert-success alert-dismissible">
<a class="close" data-dismiss="modal" aria-label="close">×</a>
<strong>Success!</strong> App information stored Successfully.
</div>
</div>
</div>
</form>
I want to have a table with checkbox on each row with django as shown in the image.
Your HTML file needs to look like this:
<form method="POST">
{{form.as_p}}
<table>
<tr>
<th>Select</th>
<th>Agent ID</th>
<th>Configuration ID</th>
<th>Host Name</th>
<th>OS Name</th>
<th>OS Version</th>
<th>Source</th>
<th>Time of Creation</th>
<th>Type</th>
</tr>
{% for apps in server %}
<tr>
{% for k,v in apps.items %}
<td><input type="checkbox" name="selected_options" value="v.id"></td>
<td>{{ v }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
{% csrf_token %}
<input type="submit" class="btn btn-info btn-lg" data-toggle="modal" data-target="#myModal" name="" value="submit">
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<div class="alert alert-success alert-dismissible">
<a class="close" data-dismiss="modal" aria-label="close">×</a>
<strong>Success!</strong> App information stored Successfully.
</div>
</div>
</div>
</form>

How to open a template as modal (detail user data) in user_list page (Django 1.11)

I have a user list page which works fine, and a user detail page which works fine too that I call from urls.py in seperate window. I want to open user detail in user list page in a modal window.
user_list.html
<table class="table table-bordered">
<thead>
<tr>
<th>Name</th>
<th>Surname</th>
<th>Email</th>
<th></th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr userid="{{user.id}}" class="edit_user">
<td>{{user.first_name}}</td>
<td>{{user.last_name }}</td>
<td>{{user.username }}</td>
<td>
<form class="right user_delete" method="POST" userid="{{user.id}}"
action="{% url 'user_delete' user.id%}">
{% csrf_token %}
<input class="btn btn-danger btn-sm" type="submit" value="DELETE">
</form>
</td>
<td><a type="button" class="btn btn-primary edit_user" href="{% url 'user_details' user.id %}" target="#edit_user"> UPDATE </a></td>
</tr>
{% empty %}
<tr>
<td>No Projects.</td>
</tr>
{% endfor %}
</tbody>
</table>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#registerformmodal"> New user </button>
user_detail.html
<h1>User Details</h1>
<p>{{ user_details.username }}</p>
<p>{{ user_details.first_name }}</p>
views.py
def user_details(request, userid):
user = User.objects.get(id=userid)
template = loader.get_template('vts/user_detail.html')
context = {
'user_details': user,
}
return HttpResponse (template.render(context, request))
The button data-target here,
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#registerformmodal"> New user </button>
looks for #registerformmodal which is neither associated with <form> nor <div>
You can add the id to your form as this
<form id="#registerformmodal" class="right user_delete" method="POST" userid="{{user.id}}">
...
</form>