where is the error in the update function? - django

i have django project that includes a form to be submit and allow user to create an update the stored data.
the problem is that once the user go the update page the system crash and display the below error :
local variable 'suspect' referenced before assignment
urls.py
path('update/<int:pk>/',update,name = 'update'),
update.html
{% extends "base.html" %}
{% load static %}
{% block body %}
<body>
<div class="lines">
<div class="line"></div><div class="line"></div>
<div class="line"></div><div class="line"></div>
<div class="line"></div><div class="line"></div><div class="line"></div>
</div>
{% for member in instance %}
<form enctype="multipart/form-data">
<div id='left-column-Input' class="formInput" include="select()">
<div class="forminputs">
<input type="text" id="fname" name="fname" autocomplete="off" required />
<label for="fname" class="label-name">
<span class="content-name" name="fname">{{member.member_name}}</span>
</label>
</div>
<div class="forminputs">
<input type="text" id="lname" name="lname" autocomplete="off" required />
<label for="lname" class="label-name">
<span class="content-name" name="lname">{{member.member_last_name}}</span>
</label></div>
<div class="forminputs">
<input type="text" id="fatherName" name="fatherName" autocomplete="off" required />
<label for="fatherName" class="label-name">
<span class="content-name" name="fatherName">{{member.member_father_name}}</span>
</label></div>
<div class="home-Button">
<button id="edit" name="edit" type="submit">Edit</button>
<button id="clear" name="clear" type="submit">Clear</button>
</div>
</div>
{% endfor %}
<script type="text/javascript">
$(document).ready(function(){
$("#edit").on('click',function(event){
event.preventDefault()
fName=$('#fname').val()
lName = $('#lname').val()
fatherName = $('#fatherName').val()
$.ajax({
url:'/blog/update',
method:'POST',
data: {
FName: fName,
LName: lName,
FatherName: fatherName,
},
headers:{
'X-CSRFToken':'{{csrf_token}}'
}
}).done(function(msg){
location.href='/blog/list'
}).fail(function(err){
alert(err)
})
})
})
</script>
</form>
</body>
{% endblock %}
views.py
def update(request,pk):
#deny anonymouse user to enter the detail page
if not request.user.is_authenticated:
return redirect("login")
else:
member = member()# the class modal
member = get_object_or_404(member, pk=pk)standard **page not found**
if request.method =="POST":
member = member()
member.member_name = request.POST['FName']
member.member_last_name = request.POST['LName']
member.member_father_name = request.POST['FatherName']
member.save()
context = {
"title":member.member_name,
"instance":member,
}
return render(request,'blog/update.html',context)
i will appreciate any help

Your URL needs pk. You're not passing suspect id as pk in your context of your return statement of your view.
path('update/<int:pk>/',update,name = 'update'),
suspect.id will work as an argument to your {% url ... %}

Related

passing a for loop value to bootstarp modal in django

Here i am trying to pass the value outside for loop modal using ajax
Here is the reference link which i followed reference link and please help me where i am wrong
here is my template.html
{% for compliance in compliance %}
{% complience_category compliance request.user as compliances %}
{% for qualification in compliances %}
.....
.....
<td>
<button data-toggle="modal" data-target="#modal-default" data-id="{{ qualification.id }}" type="button" class="btn btn-warning margin-bottom edit-qualification">
edit
</button>
</td>
....
.....
{% endfor %}
{% endfor %}
{% csrf_token %}
<div class="modal hid fade" id="modal-default">
<div class="modal-dialog">
<form class="form-horizontal" method="POST" enctype="multipart/form-data" action="{% url 'update_qualifications' qualification.id %}" ">
{% csrf_token %}
{% if qualification %}
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3>Update Compliance</h3>
</div>
<div class="modal-body">
<div class="control-group">
<label class="control-label" for="inputdate_{{qualification.id}}">Expiry Date</label>
<div class="controls">
<input type="date" id="inputdate_{{qualification.id}}" name="expiry_date" value="{{qualification.expiry_date|date:'Y-m-d'}}">
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal">Close</button>
<button class="btn btn-primary" type="submit">Save</button>
</div>
{% endif %}
</form>
</div>
</div>
here is my AJAX
<script>
$(document).on('click','.edit-qualification',function(){
var id = $(this).data('id');
console.log(id)
$.ajax({
url:'',
type:'POST',
data:{
'id':id,
'csrfmiddlewaretoken': $('input[name=csrfmiddlewaretoken]').val(),
},
success:function(data){
$('#modal-default .modal-dialog').html($('#modal-default .modal-dialog',data));
$('#modal-default').modal('show');
},
error:function(){
console.log('error')
},
});
});
</script>
Here is my views.py
#login_required
def update_qualifications(request, qualifiaction_id):
client = request.user.client
next_url = request.POST.get('next', '/')
date = request.POST.get('expiry_date') or None
record_date = request.POST.get('record_date') or None
name = request.POST.get('id_name')
compilance = request.POST.get('compliance')
document = request.FILES.get('document')
qualification = get_object_or_404(ClientUserQualification, pk=qualifiaction_id)
if document:
qualification.document = document
done = request.POST.get('done', False)
qualification.expiry_date = date
qualification.record_date = record_date
if request.user.is_admin:
qualification.validated = True
else:
qualification.validated = False
qualification.done = done
if name:
qualification.name = name
qualification.qualification_id = compilance
messages.success(request, 'Compliance was successfully updated.')
if request.user.is_admin:
qualification.save()
return redirect(next_url)
qualification.validated = False
qualification.save()
return redirect(reverse('worker_compliance_list'))
here when clicking edit of particular item it need to update only for that item
Please help me to solve this problem where i am wrong

Why edit is not working even code is correct

when I click on update, it is not updating. I don't know what to do. Everything is working except edit.
views.py:
def addnew(request):
if request.method == "POST":
form = BookForm(request.POST)
if form.is_valid():
try:
form.save()
return redirect('/')
except:
pass
else:
form = BookForm()
return render(request,'book/index.html',{'form':form})
def index(request):
books = Book.objects.all()
return render(request,"book/show.html",{'books':books})
def edit(request, id):
book = Book.objects.get(id=id)
return render(request,'book/edit.html',{'book':book})
def update(request, id):
book = Book.objects.get(id=id)
form = BookForm(request.POST,instance=book)
if form.is_valid():
form.save()
return redirect('/')
return render(request,'book/edit.html',{'book': book})
def destroy(request, id):
book = Book.objects.get(id=id)
book.delete()
return redirect("/")
urls.py:
from django.contrib import admin
from django.urls import path
from book import views
urlpatterns = [
path('admin/', admin.site.urls),
path('',views.index,name='index'),
path('addnew',views.addnew),
path('edit/<int:id>',views.edit),
path('update/<int:id>',views.update),
path('delete/<int:id>',views.destroy),
]
templates/books:
edit.html:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.10.16/js/dataTables.bootstrap4.min.js"></script>
</head>
<body>
{% block content %}
<div class="col-md-12">
<form method="post" class="post-form" action="/update/{{ book.id }}">
{% csrf_token %}
<div class="container">
<br>
<div class="form-group row">
<label class="col-sm-1 col-form-label"></label>
<div class="col-sm-4">
<h3>Update Details</h3>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">Book Id:</label>
<div class="col-sm-4">
<input type="text" class="form-control" name="id" id="id_id" required maxlength="20" value="{{book.id}}"/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">Book Name:</label>
<div class="col-sm-4">
<input type="text" class="form-control" name="name" id="id_name" required maxlength="100" value="{{book.book_name}}" />
</div>
</div>
<div class="form-group row">
<label class="col-sm-1 col-form-label"></label>
<div class="col-sm-4">
<button type="submit" class="btn btn-success btn-lg">Update</button>
</div>
</div>
</div>
</form>
{% endblock content %}
</body>
</html>
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.10.16/js/dataTables.bootstrap4.min.js"></script>
</head>
<body>
{% block content %}
<div class="col-md-12">
<form method="post" class="post-form" action="/addnew">
{% csrf_token %}
<div class="container">
<br>
<div class="form-group row">
<label class="col-sm-1 col-form-label"></label>
<div class="col-sm-4">
<!-- <h3>Enter Details</h3> -->
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">Book Name:</label>
<div class="col-sm-4">
{{ form.book_name }}
</div>
</div>
<div class="form-group row">
<label class="col-sm-1 col-form-label"></label>
<div class="col-sm-4">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</div>
</form>
</div>
{% endblock content %}
</body>
</html>
show.html:
{% block content %}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.10.16/js/dataTables.bootstrap4.min.js"></script>
</head>
<body>
<body>
<div class="container">
<div class="row">
<div class="col-md-12">
<h4>Book Records</h4> <span>Add New Book</span>
<br>
<div class="table-responsive">
<table id="bootstrapdatatable" class="table table-striped table-bordered" width="90%">
<thead>
<th><input type="checkbox" id="checkall" /></th>
<th>ID</th>
<th>Book Name</th>
<th>Edit</th>
<th>Delete</th>
</thead>
<tbody>
{% for book in books %}
<tr>
<td><input type="checkbox" class="checkthis" /></td>
<td>{{ book.id }}</td>
<td>{{ book.book_name }}</td>
<td><span style="color:brown;" class="glyphicon glyphicon-pencil"></span></p></td>
<td><span style="color:brown;" class="glyphicon glyphicon-trash"></span></p></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<script>
$(document).ready(function() {
$('#bootstrapdatatable').DataTable({
"aLengthMenu": [[3, 5, 10, 25, -1], [3, 5, 10, 25, "All"]],
"iDisplayLength": 3
}
);
} );
</script>
</body>
</body>
</html>
{% endblock content %}
Here, edit is not working. when I click on update, it is not updating. I don't know what to do. Everything is working except edit.
please anyone tell me what to do.
I have tried several times.
forms.py:
from django import forms
from book.models import Book
class BookForm(forms.ModelForm):
class Meta:
model = Book
fields = ['book_name']
widgets = { 'book_name': forms.TextInput(attrs={ 'class': 'form-control' })}
models.py:
from django.db import models
# Create your models here.
class Book(models.Model):
book_name = models.CharField(max_length=100)
class Meta:
db_table = "book"
The template of your form is wrong. Pay attention that your form is waiting for you to send it a field called book_name:
class BookForm(forms.ModelForm):
class Meta:
model = Book
fields = ['book_name']
widgets = { 'book_name': forms.TextInput(attrs={ 'class': 'form-control' })}
However, in the template you are sending it the id field and a field called name:
<input type="text" class="form-control" name="id" id="id_id" required maxlength="20" value="{{book.id}}"/>
<input type="text" class="form-control" name="name" id="id_name" required maxlength="100" value="{{book.book_name}}" />
So, according your forms.py, you must to change the template like this:
<form method="post" class="post-form" action="/update/{{ book.id }}">
{% csrf_token %}
<div class="container">
<br>
<div class="form-group row">
<label class="col-sm-1 col-form-label"></label>
<div class="col-sm-4">
<h3>Update Details</h3>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">Book Name:</label>
<div class="col-sm-4">
<input type="text" class="form-control" name="book_name" id="id_book_name" required maxlength="100" value="{{book.book_name}}" />
</div>
</div>
<div class="form-group row">
<label class="col-sm-1 col-form-label"></label>
<div class="col-sm-4">
<button type="submit" class="btn btn-success btn-lg">Update</button>
</div>
</div>
</div>
BTW, you could simplify all of this, using the power of Django like this:
<form method="post" class="post-form" action="/update/{{ book.id }}">
{% csrf_token %}
{{ form }}
<button type="submit" class="btn btn-success btn-lg">Update</button>
</form>
You should study the way in witch Django builds forms: https://docs.djangoproject.com/en/dev/topics/forms/

Display & Update in same Django form

[A newbie Question] I have a form that shows the student details (query filtered by learner_code). I have an edit button that removes the "disabled" tag from fields & let user edit the form details. I have a Save button as well. I want to save the update back to the same entry in Student model.
My views.py :
query = None
if 'learner_code' in request.GET:
query = request.GET['learner_code']
try:
student_details = Student.objects.get(learner_code=query)
except:
messages.error(request, f'Student Not Found !')
return redirect('viewstudent')
else:
context = { 'student_details' : student_details}
return render(request, 'students/viewstudent.html', context)
elif 'learner_code' in request.POST :
# Save the data back to the table
else:
return render(request, 'students/createstudent.html')
My model looks like :
class Student(models.Model):
pay = (('FULL', 'FULL'),('EMI', 'EMI'))
learner_code = models.CharField(max_length=15, null=False, primary_key=True)
certificate_name = models.CharField(max_length=150, null=False)
contact1 = models.CharField(max_length=10, null=False)
contact2 = models.CharField(max_length=10)
batch = models.CharField(max_length=10)
doj = models.DateField(null=False, default=localtime(now()).date())
payment_method = models.CharField(choices=pay, max_length=4, default='FULL')
total_paid = models.IntegerField(default=0)
def __str__(self):
return self.learner_code
My forms.py is :
class StudentCreationForm(forms.ModelForm):
class Meta:
model = Student
fields = '__all__'
My Template looks like :
{% block content %}
<div class="container mx-auto mt-3">
{% block form %}
<form class="form-row mr-auto" action="" method="get">
<input type="text" class="form-control" name="learner_code" id="search" placeholder="Learner Code" style="width: 20pc;">
<button class="btn btn-success" type="submit">Search</button>
</form>
{% if messages %}
{% for message in messages %}
<div class="container-fluid">
<div class="alert alert-{{ message.tags }}">{{ message }}</div>
</div>
{% endfor %}
{% endif %}
<hr>
<h2>STUDENT DETAILS</h2>
<div class="row my-2">
<div class="col-6">
<label for="id"><h6>LEARNER CODE : </h6></label>
<input type="text" name="id" id="id" placeholder="{{ student_details.learner_code }}" disabled style="width: 20pc;">
</div>
<div class="col-6">
<label for="name"><h6>CERTIFICATE NAME : </h6></label>
<input type="text" name="name" id="name" placeholder="{{ student_details.certificate_name }}" disabled style="width: 20pc;">
</div>
</div>
<div class="row my-2">
<div class="col-6">
<label for="contact1"><h6>CONTACT NUMBER : </h6></label>
<input type="number" name="contact1" id="contact1" placeholder="{{ student_details.contact1 }}" disabled style="width: 20pc;">
</div>
<div class="col-6">
<label for="contact2"><h6>ALT. CONTACT NO. : </h6></label>
<input type="number" name="contact2" id="contact2" placeholder="{{ student_details.contact2 }}" disabled style="width: 20pc;">
</div>
</div>
<div class="row my-2">
<div class="col-6">
<label for="batch"><h6>BATCH : </h6></label>
<input type="text" name="batch" id="batch" placeholder="{{ student_details.batch }}" disabled style="width: 20pc;">
</div>
<div class="col-6">
<label for="doj"><h6>DATE OF JOINING : </h6></label>
<input type="text" name="doj" id="doj" placeholder="{{ student_details.doj }}" disabled style="width: 20pc;">
</div>
</div>
<div class="container-fluid mx-auto mt-5">
<button onclick="edits()">Edit</button>
<form action="" method="post">
{% csrf_token %}
<button type="submit">Save</button>
</form>
</div>
<hr>
<h2>FINANCIAL INFORMATION</h2>
<div class="row my-2">
<div class="col-6">
<label for="tenure"><h6>PAYMENT TENURE : </h6></label>
<input type="text" name="tenure" id="tenure" placeholder="{{ student_details.payment_method }}" disabled style="width: 20pc;">
</div>
<div class="col-6">
<label for="paid"><h6>TOTAL PAID : </h6></label>
<input type="number" name="paid" id="paid" placeholder="{{ student_details.total_paid }}" disabled style="width: 20pc;">
</div>
</div>
{% endblock form %}
</div>
<script>
function edits()
{
document.getElementById("id").removeAttribute("disabled")
document.getElementById("id").setAttribute("value","{{ student_details.learner_code }}")
document.getElementById("name").removeAttribute("disabled")
document.getElementById("name").setAttribute("value","{{ student_details.certificate_name }}")
document.getElementById("contact1").removeAttribute("disabled")
document.getElementById("contact1").setAttribute("value","{{ student_details.contact1 }}")
document.getElementById("contact2").removeAttribute("disabled")
document.getElementById("contact2").setAttribute("value","{{ student_details.contact2 }}")
document.getElementById("batch").removeAttribute("disabled")
document.getElementById("batch").setAttribute("value","{{ student_details.batch }}")
document.getElementById("doj").removeAttribute("disabled")
document.getElementById("doj").setAttribute("value","{{ student_details.doj }}")
}
</script>
{% endblock content %}
You can use django model form and instance of the query to pre-populate the form to display and update in the same form
def your_view(request):
form = StudentCreationForm()
if request.method == "POST":
student_details = Student.objects.get(learner_code=query)
# To pre-populate the form with values using instance
form = StudentCreationForm(request.POST, instance=student_details)
if form.is_valid():
form.save()
return redirect('your_url')
return render(request, "students/createstudent.html", {'form': form })

Form Validation Not Displaying on Form

I have a custom form validation that runs on my popup window form. If the form validation occurs i get a bad request error which is what i have programmed in my views.py . How do i render it so the user stays on the form and the validation message displays. Thanks for the help. Here is my code.
#login_required
def K8_Points_Classroom(request):
#context_from_k8_points = request.session['k8_points_context']
if request.method == 'POST':
form = K8Points_ClassroomForm(request.POST)
if form.is_valid():
form.save(commit=False)
form.save()
class_name = form.cleaned_data.get('class_name')
getstudents = Student.objects.filter(class_name = class_name)
students = getstudents.all()
form = K8Points_ClassroomForm()
context = {'form': form ,'students' : students, 'class_name': class_name,}
return render(request,'points/k8_points_classroom.html', context)
else:
return HttpResponseBadRequest("Bad Request")
else:
return render(request, 'points/k8_points_classroom.html', {'form': form} )
Updated form.html
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% crispy K8Points_ClassroomForm %}
{% load static %}
{% block content %}
<br>
<h2>{% load static %}
<img src="{% static 'forms/star.png' %}" alt="chain" height="62" width="62"> {{class_name}}</h2>
<br>
<br>
<form action="/points/k8_points_classroom" method="POST">
{% csrf_token %}
<!-- Start Date -->
<div class="container">
<div class="container">
<div class='row'>
<div class="col-4">
<p> Recording Data as User : {{user.username}} </p>
</div>
</div>
<div class='row'>
<div class = "col-2">
{{form.date|as_crispy_field }}
</div>
<div class = "col-2">
{{form.week_of|as_crispy_field }}
</div>
<div class = "col-2">
{{form.day|as_crispy_field }}
</div>
</div>
</div>
</form>
<div class="jumbotron" align="middle">
<img src="{% static 'forms/levelup.png' %}" alt="levelup" height="120" width= "120">
<h1>My Students</h1>
<!-- Line Break -->
<hr style="border: 1px solid black;"/>
<!-- Line Break -->
<div class="row mb-3">
{% for i in students%}
<div class="col-md-4 themed-grid-col"><h2>{{i.student_name}}</h2>
<p align="left"> Today's Score: {{total}}</p>
<h4>
<button type="button" class="btn btn-primary btn-lg btn-block" data-toggle="modal"
data-target="#PointsBox{{ student.pk }}">Level Up
</button>
</h4>
<div id="PointsBox{{ student.pk }}" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<img src="{% static 'forms/star.png' %}" align="left" alt="chain" height="42"
width="42">
<h4 class="modal-title">Points Confirmation </h4>
<button type="button" class="close" data-dismiss="modal"> ×</button>
</div>
<div class="modal-body">
<h6>
<div class="modal-body">Please add the selected points for the current
student.</div>
</h6>
<form action="/points/k8_points_classroom" method="POST">
{% csrf_token %}
<div class="form-row" align='left'>
<div class="col-7">
{{form.class_name|as_crispy_field }}
<input type="student_name" class="form-control" value ="{{i}}" >
{{form.time_frame|as_crispy_field }}
</div>
</div>
<div class="form-row">
<div class="col-3" align='left'>
{{form.behavior|as_crispy_field }}
{{form.academic|as_crispy_field }}
<button type="submit" class="btn btn-success" ><i
class="fas fa-star"></i> Level Up
</button>
</div>
</div>
</div>
<div class="modal-foot"></div>
</div>
</div>
</div>
</div>
</form>
{% endfor %}
{% endblock %}
You can't return a bad response if the form is invalid. Instead, render the page again with the invalid form and in the temolate you will be able to render the errors. Try starting rendering the form just using {{ form.as_p }} and you will see the errors. The form errors are in form.errors and each field has its own errors, you can access to them form.field.erorrs
if request.method == 'POST':
form = K8Points_ClassroomForm(request.POST)
if form.is_valid():
form.save(commit=False)
form.save()
class_name = form.cleaned_data.get('class_name')
getstudents = Student.objects.filter(class_name = class_name)
students = getstudents.all()
form = K8Points_ClassroomForm()
context = {'form': form ,'students' : students, 'class_name': class_name,}
return render(request,'points/k8_points_classroom.html', context)
return render(request, 'points/k8_points_classroom.html', {'form': form} )

Saving edited data back to database using django and knockout

I am trying to figure out how to save edited data back to the database using django forms and knockout. The edit.html file has been changed to use knockout to display and edit information on the edit page. I need to figure out how to change the views.py file to save the information. The page seems to be behaving how I want it to (I think...), but I don't know how to update the information back to the database once editing has occurred since I am not using django fields in the .html file.
I have read this thread: using knockout.js with django forms?, but that is using fields in the html file instead of the knockout code. I'm not opposed to going that route if that is a better method, but was struggling a little with the implementation of that idea when I tried it.
The relevant info from the views.py file:
#render_to('phones/edit.html')
def EditPhone(request, number):
p_number = PhoneTable.objects.get(number=number)
customer_list = list(Customer.objects.values('customer_id'))
JSON_customer_list = json.dumps(customer_list)
if not request.POST:
return dict(
form=PhoneForm(instance=p_number),
CallType=p_number.call_type,
number=number,
Customer=p_number.customer_id,
extension=p_number.profile.extension,
department=p_number.profile.department,
JSON_customer_list=JSON_customer_list
)
form = PhoneForm(request.POST, instance=p_number)
if not form.is_valid():
return dict(form=form)
form.save()
messages.success(request, 'Phone Number updated')
return redirect('phones:available_phones', number=p_number.number)
class PhoneForm(ModelForm):
class Meta:
model = PhoneTable
This is the html file:
{% block pagetitle %}Edit Phone Number: {{ number }}{% endblock %}
{% block content %}
<div class="row">
<div class="span2">
<div class="pull-right">Call Type:</div>
</div>
<div class="span6">
<select data-bind="options: callTypes, value: callType"></select>
</div>
</div>
<div class="row">
<!-- ko if: callType() === "Direct" -->
<div class="span2">
<div class="pull-right">Extension:</div>
</div>
<div class="span6">
<input type="text" data-bind="value: editExtension" />
</div>
<!-- /ko -->
</div>
<div class="row">
<!-- ko if: callType() === "Sales" -->
<div class="span2">
<div class="pull-right">Customer:</div>
</div>
<div class="span6">
<select data-bind="options: customerDisplays, value: selectedCustomer"></select>
</div>
<!-- /ko -->
</div>
<div class="row">
<!-- ko if: callType() === "Service" -->
<div class="span2">
<div class="pull-right">Service Profile:</div>
</div>
<div class="span6">
<select data-bind="options: servProfiles, value: servProfile"></select>
</div>
<!-- /ko -->
</div>
<div class="form-actions">
<input type="submit" class='btn btn-primary' value="Update" />
<a class="btn" href="{% url phones:available_phones %}">Cancel</a>
</div>
{% endblock %}
{% block javascript_compress %}
<script type='text/javascript' src="{% static 'js/knockout/knockout.js' %}"></script>
<script type="text/javascript">
$(function(){
customerListFromServer = {{ JSON_customer_list|safe }};
var PhoneViewModel = function() {
var self = this;
customerList = [];
for (var key in customerListFromServer) {
customerList.push(customerListFromServer[key].customer_id);
}
self.callTypes = ko.observableArray(['Free', 'Direct', 'Sales', 'Service']);
self.callType = ko.observable("{{ CallType }}");
self.editExtension = ko.observable("");
self.servProfiles = ko.observableArray(["{{ extension }}", "{{ department }}"]);
self.servProfile = ko.observable();
self.customerDisplays = ko.observableArray(customerList);
self.selectedCustomer = ko.observable();
}
ko.applyBindings(new PhoneViewModel());
});
</script>
{% endblock %}
Any suggestions? If I am missing something, please let me know. Thank you.
I figured this out, so I will post how if it can help anyone else.
I added a form id and post method along with a hidden field to the html file. As Kevin suggested, I used a data-bind on the submit button and added a submit function to the ko viewModel. Then I changed the views.py file to get the json data and to save the edited values.
#render_to('phones/edit.html')
def EditPhone(request, number):
p_number = PhoneTable.objects.get(number=number)
customer_list = list(Customer.objects.values('customer_id'))
JSON_customer_list = json.dumps(customer_list)
if not request.POST:
return dict(
form=PhoneForm(instance=p_number),
CallType=p_number.call_type,
number=number,
Customer=p_number.customer_id,
extension=p_number.profile.extension,
department=p_number.profile.department,
JSON_customer_list=JSON_customer_list
)
json_data = request.POST.get('json_blob')
obj = loads(json_data)
p_number.call_type = obj.get("callType")
p_number.customer_id = obj.get("selectedCustomer")
p_number.profile.extension = obj.get("editExtension")
p_number.profile.department = obj.get("servProfile")
p_number.save()
messages.success(request, 'Phone Number updated')
return redirect('phones:available_phones')
class PhoneForm(ModelForm):
class Meta:
model = PhoneTable
The html file:
{% block pagetitle %}Edit Phone Number: {{ number }}{% endblock %}
{% block content %}
<form id="phone_form" method="post">
{% csrf_token %}
<input type="hidden" id="json_blob" value="" />
<fieldset>
<div class="row">
<div class="span2">
<div class="pull-right">Call Type:</div>
</div>
<div class="span6">
<select data-bind="options: callTypes, value: callType"></select>
</div>
</div>
<div class="row">
<!-- ko if: callType() === "Direct" -->
<div class="span2">
<div class="pull-right">Extension:</div>
</div>
<div class="span6">
<input type="text" data-bind="value: editExtension" />
</div>
<!-- /ko -->
</div>
<div class="row">
<!-- ko if: callType() === "Sales" -->
<div class="span2">
<div class="pull-right">Customer:</div>
</div>
<div class="span6">
<select data-bind="options: customerDisplays, value: selectedCustomer"></select>
</div>
<!-- /ko -->
</div>
<div class="row">
<!-- ko if: callType() === "Service" -->
<div class="span2">
<div class="pull-right">Service Profile:</div>
</div>
<div class="span6">
<select data-bind="options: servProfiles, value: servProfile"></select>
</div>
<!-- /ko -->
</div>
<div class="form-actions">
<input type="submit" class='btn btn-primary' value="Update" data-bind="click: submitForm" />
<a class="btn" href="{% url phones:available_phones %}">Cancel</a>
</div>
{% endblock %}
{% block javascript_compress %}
<script type='text/javascript' src="{% static 'js/knockout/knockout.js' %}"></script>
<script type="text/javascript">
$(function(){
customerListFromServer = {{ JSON_customer_list|safe }};
var PhoneViewModel = function() {
var self = this;
customerList = [];
for (var key in customerListFromServer) {
customerList.push(customerListFromServer[key].customer_id);
}
self.callTypes = ko.observableArray(['Free', 'Direct', 'Sales', 'Service']);
self.callType = ko.observable("{{ CallType }}");
self.editExtension = ko.observable("");
self.servProfiles = ko.observableArray(["{{ extension }}", "{{ department }}"]);
self.servProfile = ko.observable();
self.customerDisplays = ko.observableArray(customerList);
self.selectedCustomer = ko.observable();
self.submitForm = function() {
$("#json_blob").val(ko.toJSON(self));
$("#phone_form").submit();
}
}
ko.applyBindings(new PhoneViewModel());
});
</script>
{% endblock %}
With knockout, i typically like to control as much as possible through the view model, including saving information back to the server. in your case, i would have the submit button execute a save function inside the view model like so:
html:
<input type="submit" class='btn btn-primary' value="Update" data-bind="click: submitForm" />
in your knockout view model, there are a couple of ways you can save the data:
self.submitForm = function () {
// save via postback
ko.utils.postJson('/EditPhone', ko.toJSON(self));
// save via ajax
$.ajax({
type: 'POST',
data: ko.toJSON(self),
url: '/EditPhone',
success: function () {
alert("saved");
},
error: function () {
alert("no worky");
}
})
}
unfortunately, i have no experience with django so im not sure exactly how you need to set that up in order to accept the json data coming back to the server