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
Related
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.
I want to display card first which have status=True, so how can i arrange it by status in my views.py or in template
this is my views.py:
def myItem(request):
context = {}
if Item.objects.filter(status=True).exists():
context['data'] = Item.objects.all()#here i am taking all data but i want to arrange it so that which data have status=True will come first.
else:
context['data'] = Item.objects.all()
context['data_false'] = True
return render(request,'frontend/myeoffice.html',context)
this is in my Template:
{% for i in data %}
{% if i.status %}
<div class="col-xl-4">
<div class="card shadow-sm p-4">
<div class="card-header p-0 text-center">
<h2 class="title">{{i.name}}</h2>
</div>
<div class="content text-break p-2">
<p class="copy">{{i.description|truncatechars:100}}</p>
</div>
<div class="card-footer text-left p-0">
<button class="btn btn-primary m-3">View</button>
</div>
</div>
</div>
{% else %}
<div class="col-xl-4">
<div class="card shadow-sm p-4" data-toggle="modal" data-target=".bd-example-modal-lg" style="background: #ccc;">
<div class="card-header p-0 text-center">
<h2 class="title">{{i.name}}</h2>
</div>
<div class="content text-break p-2">
<p class="copy">{{i.description|truncatechars:100}}</p>
</div>
<div class="card-footer text-left p-0">
<button class="btn btn-primary disabled m-3" data-toggle="modal" data-target=".bd-example-modal-lg">
View
</button>
</div>
</div>
</div>
{% endif %}
{% endfor %}
NOTE : I want data which have both status=False and status=True but order should be True first and False last
You want to do this with the query to get the first one out of the result where status is True.
context['data'] = Item.objects.filter(status=True).first()
This will give you the first result with this status. Or if you want all results and order it by the status then do this:
context['data'] = Item.objects.all().order_by('-status')
You can arrange the results via the order function:
def myItem(request):
context = Item.objects.all().order_by('-status')
return render(request,'frontend/myeoffice.html',context)
The - in -status is used to reverse order.
I have 2 models WorkoutCategory and workout with a ForeignKey with workout_Category in catig
in my template i have a collapsed div "WorkoutCategory" include a collapse form "to save in workoutmodel
the question is how I should pass the catig_id if it's not included in the form
below screenshot to simplify my idea
collapsed div for woroutcategory and the form
models:
from django.db import models
# Create your models here.
class WorkoutCategory(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Workout(models.Model):
catig = models.ForeignKey(WorkoutCategory,null=True, on_delete=models.CASCADE)
workout_name = models.CharField(max_length=250)
video_link = models.CharField(max_length=300)
def __str__(self):
return self.workout_name
the Form:
from django.forms import *
from .models import *
from django import forms
class CreateWorkoutForm(ModelForm):
class Meta:
model = Workout
exclude = ['catig']
widgets = {
'workout_name' : forms.TextInput(attrs={'class':'form-control','placeholder':'Workout Name'}),
'video_link' : forms.URLInput(attrs={'class':'form-control','placeholder':'https://www.youtube.com/ ...'}),
}
the Template:
{% for catg in allcetgs %}
<br>
<div class="card-header" data-toggle="collapse" href="#multiCollapseExample{{catg.id}}" role="button" aria- expanded="false" aria-controls="multiCollapseExample{{catg.id}}">
{{catg.name}}</div>
<div class="row">
<div class="col">
<div class="collapse multi-collapse" id="multiCollapseExample{{catg.id}}">
<div class="col">
<br>
<div class="btn btn-success" data-toggle="collapse" href="#addingworkout{{catg.id}}" role="button" aria-expanded="false" aria-controls="addingworkout{{catg.id}}" style="float: right;">add workout</div>
<br> <br>
<div class="collapse multi-collapse" id="addingworkout{{catg.id}}" >
<form method="POST" action="">
{% csrf_token %}
<div class="form-row">
<div class="col">
{{workoutForm.workout_name}}
</div>
<div class="col">
{{workoutForm.video_link}}
</div>
<button type="submit" class="btn btn-primary">Save</button>
</div>
</form>
</div>
</div>
<br>
<table class="table">
<thead>
<tr>
<th scope="col">Workout Name</th>
<th scope="col">Youtube Link</th>
</tr>
</thead>
<tbody>
{% for wkout in catg.workout_set.all %}
<tr>
<td>{{wkout.workout_name}}</td>
<td>check video</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
I don't want the user it set the catig_id since it's already the parent div of the form. how should I pass that catig_id value
# You don't need to exclude the catig field in your form
class CreateWorkoutForm(ModelForm):
class Meta:
model = Workout
widgets = {
'workout_name' : forms.TextInput(attrs={'class':'form-control','placeholder':'Workout Name'}),
'video_link' : forms.URLInput(attrs={'class':'form-control','placeholder':'https://www.youtube.com/ ...'}),
}
# you can have the value of catig_id in the hidden input
<div class="collapse multi-collapse" id="addingworkout{{catg.id}}" value="{{catg.id}}">
<form id="addingworkout">
<div class="form-row">
<input type="hidden" name="catig" value="{{catg.id}}">
<div class="col">
{{workoutForm.workout_name}}
</div>
<div class="col">
{{workoutForm.video_link}}
</div>
<button type="submit" class="btn btn-primary">Save</button>
</div>
</form>
</div>
html file
Here I list the client and Process in the input tag
And select the and submit
{% extends 'client_pannel.html' %}
{% block content %}
<script>
function postConfirm() {
if (confirm('Are you sure you want to delete this client')) {
yourformelement.submit();
} else {
return false;
}
}
</script>
<form method="POST">
{% csrf_token %}
<div class="breadcome-area">
<div class="container-fluid">
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="breadcome-list single-page-breadcome">
<div class="row">
<div class="col-lg-10 col-md-6 col-sm-6 col-xs-12">
<div class="breadcome-heading">
<form role="search" class="sr-input-func">
<label>{{ emp.first_name }} {{ emp.last_name }}</label>
</form>
</div>
</div>
<div class="col-lg-2 col-md-6 col-sm-6 col-xs-12">
<a href="/employee_list/"> <button type="submit"
class="btn btn-info add-new">Submit</button></a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="data-table-area mg-b-15">
<div class="container-fluid">
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="sparkline13-list">
<div class="sparkline13-graph">
<div class="datatable-dashv1-list custom-datatable-overright">
<table id="table" data-toggle="table" data-pagination="true" data-search="true"
data-show-columns="true" data-show-pagination-switch="true" data-show-refresh="true"
data-key-events="true" data-show-toggle="true" data-resizable="true"
data-cookie="true" data-cookie-id-table="saveId" data-show-export="true"
data-click-to-select="true" data-toolbar="#toolbar">
<thead>
<tr>
<th>Process</th>
</tr>
</thead>
<tbody>
{% for client in form %}
<tr>
<td>
<input type="checkbox" name="cname[]" value="{{ client.id }}">
{{ client.Name }}
</td>
<td>
{% for process in client.clients %}
<input type="checkbox" name="process[]" value="{{ process.id }}">
{{ process.process }}<br />
{% endfor %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
{% endblock %}
views file
The below code is get the selected in checkbox. The getlist method return nothing
if request.method == "POST":
cname = request.POST.getlist('cname[]')
print("cname", cname)
process = request.POST.getlist('process[]')
print("process", process)
I wanted to use class based views and went through the django documentation and I get noerror messages but wind up with an empty template. I had it working with the non-classed based views. How do I reformat the code so that it renders the template? The template consists of a title, some headings, a navigational menu, flags for selecting instructions in different languages,
followed by a form which shows a flag, policy name char field, and a check box control. I think the initial = {'key': 'value'} in the view forms incorrect but I don't know what to replace it with. Thanks in advance.
forms.py
from django import forms
from policytracker.models import Flag, Label_Links
class PolicyStartForm( forms.Form ):
flags = Flag.objects.all()
policy = Label_Links.objects.all().filter(iso_language='en')[0]
frm_policy1_name=[]
for flag in flags:
frm_policy1_name.append(forms.CharField(max_length=40))
policy_dict = { 'new_policy_link' :policy.nav_section_new_policy_link,
'new_policy_label' :policy.nav_section_new_policy_label,
'graphs_link':policy.nav_section_graphs_link,
'graphs_label' :policy.nav_section_graphs_label,
'account_link' :policy.nav_section_account_link,
'account_label' :policy.nav_section_account_label,
'policy_list_link':policy.nav_section_list_policies_link,
'policy_list_label':policy.nav_section_list_policies_label,
'login_link' :policy.nav_section_login_link,
'login_label' :policy.nav_section_login_label,
'new_policy1_heading' :policy.new_policy1_heading,
'new_policy1_title_label':policy.new_policy1_title_label,
'policy_needs_translation_label':policy.new_policy1_needs_trans_label,
'policy1_submit_label': policy.new_policy1_submit_button_label,
'policy1_tip_msg' :policy.new_policy1_tip_msg,
't_logged_in' :True,
'frm_policy_name' :frm_policy1_name,
't_flags' :flags }
</code>
<code>
views.py
# coding=utf-8
from django.shortcuts import render
from django.http import HttpResponseRedirect
from policytracker.forms import LoginForm, PolicyStartForm
from policytracker.models import Flag, Label_Links
from django.views import View
class PolicyStartView(View):
template_name = 'policystart.html'
initial = {'key': 'value'}
form_class = PolicyStartForm
def get(self, request, *args, **kwargs):
form = self.form_class(initial=self.initial)
return render(request, self.template_name, {'form': form})
</code>
<code>
policystart.html
{% extends "policy-base.html" %}
{% block navsection %}
<div class="container top">
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<h1 class="text-center">{{ new_policy1_heading }}</h1>
</div>
</div>
{% if t_policy_details %}
<div class="row">
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-4">
<h4 class="text-nowrap text-left" id="week_start">2017-02-11</h4></div>
<div class="col-md-4 col-xs-4">
<h4 class="text-center" id="week_number">Week 1</h4></div>
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-4">
<h4 class="text-nowrap text-right" id="week_end">2016-09-18</h4></div>
</div>
{% endif %}
<div class="row">
<div class="col-md-12">
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<div class="navbar-header"><a class="navbar-brand hidden navbar-link" href="#"> Policies</a>
<button class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navcol-1"><span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button>
</div>
<div class="collapse navbar-collapse" id="navcol-1">
<ul class="nav navbar-nav navbar-right">
<li class="hidden" role="presentation">{{ new_policy_label }}</li>
<li {% if not t_logged_in %} class="hidden" {% endif %} role="presentation">{{ graphs_label }}</li>
<li {% if not t_logged_in %} class="hidden" {% endif %} role="presentation">{{ account_label }}</li>
<li role="presentation">{{ policy_list_label }}</li>
{% if not t_logged_in %} <li role="presentation">{{ login_label }}</li> {% endif %}
</ul>
</div>
</div>
</nav>
</div>
</div>
{% include "pol-new1-lang.html" %}
</div>
<div class="container middle-container">
<div class="row">
<div class="col-lg-1 col-md-1 col-sm-1 col-xs-3">
<p> </p>
</div>
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-8">
<h4>{{ new_policy1_title_label }}</h4>
</div>
<div class="col-lg-1 col-md-1 col-sm-1 col-xs-1">
<h4 class="text-center">{{ policy_needs_translation_label }}</h4>
</div>
</div>
<form method="POST">
{% csrf_token %}
{% load static %}
{% for f in t_flags %}
<div class="row flag">
<div class="col-lg-1 col-md-1 col-sm-1 col-xs-2"><img src="{% static f.flag_image_filename %}"></div>
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-9">
<input class="form-control" type="text" name="policytitle">
</div>
<div class="col-lg-1 col-md-1 col-sm-1 col-xs-1">
<input class="form-control" type="checkbox" name="needstranslation">
</div>
</div>
{% endfor %}
<div class="row enter">
<div class="col-lg-1 col-md-1 col-sm-1 col-xs-3">
<p> </p>
</div>
<div class="col-lg-9 col-md-9 col-sm-9 col-xs-8">
<button class="btn btn-default" type="submit">{{ policy1_submit_label }}</button>
</div>
</div>
</form>
<div class="row enter">
<div class="col-lg-1 col-md-1 col-sm-1 col-xs-3">
<p> </p>
</div>
<div class="col-lg-9 col-md-9 col-sm-9 col-xs-8">
<p>{{ policy1_tip_msg }}</p>
</div>
</div>
</div>
{% endblock %}
</code>
You're using a load of variables in your template, but you aren't actually sending any of them to the context; the only thing your view passes is form. If you want to use things like new_policy1_heading, policy_needs_translation_label and t_flags you need to define them in your view and send them to the template from there.
Actually, it looks like you've completely misunderstood the jobs of forms and views. All the code you've currently put inside your form actually belongs in the view, and you should use policy_dict as the template context. It doesn't look like you need a form class at all.
Even there, though, you're doing much more work than you need to. There's no need to send all the specific fields of the policy object individually; just send policy and then in the template you can do {{ policy.policy_needs_translation_label }} etc.