How to Pass an Image File to a API Endpoint - json

I have a web services with DRF, I have POSTMAN passing the right all fields right with success including the image file ['avatar']
[]1
Now how do i pass the image file from a Django Form, but i keep getting Error 400, Bad request. Please how do i encode the image file to be passed into the API endpoint .
html
<form method="post" action="#" enctype="multipart/form-data">
{% csrf_token %}
<label for="phone">Enter Phone</label>
{{ form.phone }} <br />
<label for="bvn">Enter BVN</label>
{{ form.bvn }} <br />
<label for="avatar">Upload Avatar</label>
{{ form.avatar }} <br />
<button type="submit" class="btn btn-primary" >Submit</button>
</form>
views.py
def form_valid(self, form):
token = self.request.session['session_token']
headers = {"Content-Type": 'application/json', "Authorization": "Token " + token}
parameters = {
'bvn': form.cleaned_data['bvn'],
'phone': form.cleaned_data['phone'],
'avatar': self.request.FILES['avatar']
}
response = requests.put(str(settings.API_END_POINT + '/customer_profile_api/'), data=parameters,
headers=headers)
if response.status_code in settings.SUCCESS_CODES:
messages.success(self.request, 'Successfully updated profile')
else:
messages.error(self.request, 'API Error %s' % response.status_code)
return super(CustomerDashboard, self).form_valid(form)
form.py
class ProfileUpdateForm(forms.Form):
"""customer profile update form"""
phone = forms.CharField(required=False, widget=NumberInput(attrs={'class': 'form-control',
'type': 'number', 'id': 'phone',
'placeholder': 'Enter Phone Number'}))
bvn = forms.CharField(required=False, widget=NumberInput(attrs={'class': 'form-control',
'type': 'number', 'id': 'bvn',
'placeholder': 'Enter BVN'}))
avatar = forms.ImageField(required=False, widget=ClearableFileInput(attrs={'class': 'form-control',
'type': 'file', 'id': 'avatar',
'placeholder': 'Upload Avatar'}))

Yours headers is wrong.
headers = {"Content-Type": 'application/json', "Authorization": "Token " + token}
change to:
headers = {"Content-Type": 'multipart/form-data', "Authorization": "Token " + token}
When you upload some file you should use multipart/form-data instead of application/json
(If you certainly do not send the file as base64)

Should someone else run into the same issue, The only way i was able to solve it is to have separate views to handle image and other text fields. What i did so far that worked.
If you noticed, the content-type header for the view that handles the image wasnt inserted, Just remove it and let it your API handle it by itself, several times i set it as multipart/form-data, i will hit response code 200/201, but file never get saved.
my API views.py
class CustomerApiView(generics.UpdateAPIView, generics.ListAPIView):
"""Customer Api View to update customer profile"""
http_method_names = ['put', 'get']
renderer_classes = [renderers.JSONRenderer]
authentication_classes = [authentication.TokenAuthentication]
serializer_class = CustomerSerializer
queryset = Profile.objects.all()
permission_classes = [IsAuthenticated]
def get_queryset(self):
user = self.request.user
return self.queryset.filter(user=user)
def get_object(self):
queryset = self.filter_queryset(self.get_queryset())
# make sure to catch 404's below
obj = queryset.get(user_id=self.request.user.id)
self.check_object_permissions(self.request, obj)
return obj
class CustomerAvatarApiView(generics.UpdateAPIView):
"""Customer Avatar/DP API View"""
serializer_class = CustomerAvatarSerializer
queryset = Profile.objects.all()
authentication_classes = [authentication.TokenAuthentication]
permission_classes = [IsAuthenticated]
renderer_classes = [renderers.JSONRenderer]
http_method_names = ['put', 'get']
def get_object(self):
queryset = self.filter_queryset(self.get_queryset())
# make sure to catch 404's below
obj = queryset.get(user_id=self.request.user.id)
self.check_object_permissions(self.request, obj)
return obj
serializer.py
class CustomerSerializer(serializers.ModelSerializer):
"""Customer Profile Serializer"""
class Meta:
"""Class Meta"""
model = Profile
fields = ('pk', 'phone', 'bvn', 'avatar')
extra_kwargs = {'pk': {'read_only': True}, }
class CustomerAvatarSerializer(serializers.ModelSerializer):
"""Separate Serializer to handle upload of file"""
class Meta:
"""Class Meta"""
model = Profile
fields = ('avatar', )
my view.py
class CustomerDashboard(LoginRequiredMixin, generic.FormView):
"""customer dashboard view"""
template_name = 'customer/dashboard.html'
form_class = ProfileUpdateForm
raise_exception = False
success_url = reverse_lazy('customer_dashboard')
def get_profile_api(self):
"""get profile api call to fetch profile; passing in the token from session"""
token = self.request.session['session_token']
headers = {"Content-Type": 'application/json', "Authorization": "Token " + token}
response = requests.get(str(settings.API_END_POINT + '/customer_profile_api/'), headers=headers)
json_response = response.json()
return json_response
def get_initial(self):
initial = ''
try:
initial = super(CustomerDashboard, self).get_initial()
initial['phone'] = self.get_profile_api()[0]['phone']
initial['bvn'] = self.get_profile_api()[0]['bvn']
except:
pass
return initial
def get_context_data(self, **kwargs):
"""overriding get_context_data to pass data to template"""
context = super(CustomerDashboard, self).get_context_data()
if self.get_profile_api()[0]['bvn'] != '': # if BVN has been filled before pass True or False to template
context['bvn_initial'] = True # Todo Validate BVN from API Before calling save method on it
else:
context['bvn_initial'] = False
return context
def form_valid(self, form):
token = self.request.session['session_token']
if 'updateAvatar' in self.request.POST:
headers = {"Authorization": "Token " + token}
avatar = form.cleaned_data['avatar']
file = {'avatar': (str(avatar), avatar)}
response = requests.put(str(settings.API_END_POINT + '/customer_profile_avi_api/'), files=file,
headers=headers)
message = 'Avatar changes successfully'
if response.status_code in settings.SUCCESS_CODES:
messages.success(self.request, message)
else:
messages.error(self.request, 'API Error %s' % response)
elif 'updateProfile' in self.request.POST:
headers = {"Content-Type": "application/json", "Authorization": "Token " + token}
parameters = {
'bvn': form.cleaned_data['bvn'],
'phone': form.cleaned_data['phone'],
}
response = requests.put(str(settings.API_END_POINT + '/customer_profile_api/'), json=parameters,
headers=headers)
message = 'Profile changes successfully'
if response.status_code in settings.SUCCESS_CODES:
messages.success(self.request, message)
else:
messages.error(self.request, 'API Error %s' % response)
return super(CustomerDashboard, self).form_valid(form)

Related

Object of type date is not JSON serializable (error in tests.py)

I wrote this view to register with the user's phone and the view itself works fine
But in test def test_signup_phone_post (self)
For response = self.client.post (reverse ('signup_phone'), self.user, follow = True)
This gives the error: TypeError: Object of type date is not JSON serializable
views.py
class SignupPhoneView(View):
def get(self, request):
form = SignupPhoneForm()
return render(request, 'user/signup_phone.html', {'form': form})
def post(self, request):
form = SignupPhoneForm(request.POST)
if User.objects.filter(username=request.POST.get("username") + "#mail.com"): # If username already exists
logger_warn.warning(f'class SignupPhoneView, {request.POST.get("username")}, Registration exists')
return redirect("/user/signup-phone/", messages.error(request, "Registration exists"))
elif form.is_valid():
token = random.randint(100000, 999999)
kave_negar_token_send(form.cleaned_data['recovery_phone'], token)
code = OtpCode.objects.create(phone_number=form.cleaned_data['recovery_phone'], code=token)
print(code)
request.session['signup_info'] = {
'username': form.cleaned_data['username'],
'password': form.cleaned_data['password'],
'first_name': form.cleaned_data['first_name'],
'last_name': form.cleaned_data['last_name'],
'birthday': form.cleaned_data['birthday'],
'gender': form.cleaned_data['gender'],
'country': form.cleaned_data['country'],
'recovery_phone': form.cleaned_data['recovery_phone']
}
messages.success(request, f'{request.POST.get("username")} please enter your verification code')
return redirect("/user/phone-verify/")
else:
logger_error.error(f'class SignupEmailView, {request.POST.get("username")}, Registration failed')
messages.error(request, "Registration failed")
return redirect("/user/signup-phone/")
tests.py
class SignupPhoneTest(TestCase):
def setUp(self):
self.user = {
'username': 'testuser',
'password': '7895146',
'recovery_phone': '09874563215',
'first_name': 'lina',
'last_name': 'wong',
'birthday': '01/10/2000',
'gender': 'f',
'country': 'England'
}
def test_signup_phone_page_url(self):
response = self.client.get("/user/signup-phone/")
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, template_name='user/signup_phone.html')
def test_signup_phone_post(self):
response = self.client.post(reverse('signup_phone'), self.user, follow=True)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.redirect_chain, [(reverse('phone_verify'), 302)])

Django pass data from HTML table to database model

I am creating a student attendance system using django. I am fetching all student's names from the student database into an HTML table and updating information about students to django model.
This is my view.py to get data
def attendanceFill (request, subject):
context = ''
ad_standard = request.session.get('standardO')
subjects = CustomStudent.objects.filter(className__name__contains = ad_standard, subjectName__subjects__contains = subject)
# attendanceForm = Attendance(request.POST or None, instance=subjects)
print(ad_standard)
print(subject)
print(subjects)
context = {'subjects' : subjects}
if request.method == 'POST':
student = request.POST
print(student)
return render(request, 'teacher/attendance_fill.html', context)
This is my HTML template for data handling.
<div class="container">
<div class= "row mt-4">
<form action="" method="POST">
{% csrf_token %}
<table>
{% for student in subjects %}
<tr>
<td name= 'student'><p class="student-name" id="student-name">{{ student.sname }}</p></td>
<td>
<input type="checkbox" name="attendance" id="attendance">
</td>
</tr>
{% endfor %}
<tr>
<td>
<button type="button" name="checked" id = "checked" class="btn btn-outline-dark mb-4 shadow" style="border-radius:25px;">Submit</button>
</td>
<td></td>
</tr>
</table>
</form>
</div>
</div>
This is jquery function I am using to capture data.
var formData = new FormData()
$(document).ready(function(){
$("#checked").click('click', function(){
$students = document.getElementsByClassName('student-name').textContent;
$attendance = $('#attendance').val()
console.log($students)
console.log($attendance)
})
})
I have tried $('student-name').val() to get value for all students but it returns blank. Nothing is captured with this method.
I wish capture all data and update it into attendance model.
This are my models:
# Custom Student Table
class CustomStudent(models.Model):
_id = models.AutoField
sname = models.CharField(max_length = 50)
slname = models.CharField(max_length = 50)
admissionNo = models.CharField(default= "", max_length=50)
parentName = models.CharField(default= "", max_length=100)
emerContact = models.CharField(default= "", max_length=50)
contactNo = models.CharField(default= "", max_length=50)
className = models.ForeignKey(Standard, on_delete=models.DO_NOTHING)
subjectName = models.ManyToManyField(Subject)
Year = models.CharField(default="", max_length=5)
email = models.CharField(default="", max_length=60)
address = models.CharField(default="", max_length=250)
def __str__(self):
# return str(self.slname)
return str(self.sname)
AttendenceChioces = [
('Y', 'Yes'),
('N', 'No')
]
# Student Attendance Table
cla
AttendanceStudent(models.Model):
attendace_id = models.AutoField(primary_key= True)
student = models.ForeignKey(CustomStudent, on_delete=CASCADE)
attendace = models.CharField(max_length = 50, choices=AttendenceChioces)
date = models.DateField(auto_now= True)
teacher = models.CharField(max_length=255)
def __str__(self):
return str(self.sname)
Is there any other efficient way to submit attendance data into database. I have tried capturing all data using jquery but it returns blank.
UPDATE:
I have figured out proper way to send data but issue is django is not receiving any data in view funtion. I have created a view function to process data as my current view function attendancefill cannot process url without subject value.
def attendanceFilled(request):
print(request.POST)
if request.method == 'POST':
print (request.POST)
return JsonResponse({'data' : request.POST}, status=200)
return render(request, 'teacher/attendance_st.html')
I have verified via console.log and chrome DevTools tat ajax is sending data. But in django there is no data. I have tried printing new data at all points in new view function. It always returns a empty dict.
This is my updated jquery:
var value = []
$(document).ready(function(){
$("#checked").click('click', function(){
csrf = $("input[name=csrfmiddlewaretoken]").val();
value.push({'csrfmiddlewaretoken' : '{{ csrf_token }}'})
$('#attendance_table tr').each(function(a,b){
$student = $('.student-name', b).text();
$present = $('#attendance', b).prop('checked');
value.push({Student : $student, Present : $present})
})
var datatoadd = JSON.stringify(value);
document.getElementById("demo").innerHTML = datatoadd;
console.log(datatoadd)
$.ajax({
type: "POST",
url: '{% url "attendanceFilled" %}',
data: datatoadd,
cache: false,
processData: false,
contentType: false,
success: function(){
alert('Attendance submitted')
},
error: function(xhr, errmsg, err){
console.log(xhr.status + ":" + xhr.responseText)
alert('Attendance Failed to Submit! Please contact adminitstrator with your issue!')
}
})
})
})
my path in urls:
path('subject/<slug:subject>/', views.attendanceFill, name="subject"),
path('attendanceFilled', views.attendanceFilled, name="attendanceFilled"),
I am only posting required URLs here my URL file is too big.
#Sahil Mohile- Your model needs some clean-up.
class StudentAttendance(models.Model):
attendance_id = models.AutoField(primary_key= True)
student = models.ForeignKey(CustomStudent, on_delete=CASCADE,db_index=True)
attendace = models.CharField(max_length = 20, choices=AttendenceChioces)
date = models.DateField(auto_now= True)
teacher = models.ForeignKey(settings.AUTH_USER_MODEL)#Dont call it #tname, explicit is better than implicit.
def __str__(self):
return str(self.sname)
Now. my main point. Attendance record is tied to a Term/Semester. How about you
create a Semester Table. Tie the student attendance with a specific semester/term
import datetime
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
def current_year():
return datetime.date.today().year
def max_value_current_year(value):
return MaxValueValidator(current_year())(value)
class Semester(models.Model):
name = models.CharField(max_length=50)
year = models.PositiveIntegerField(
default=current_year(), validators=[MinValueValidator(1984), max_value_current_year])
.........
e.g Fall 2020
class StudentAttendance(models.Model):
attendance_id = models.AutoField(primary_key= True)
semester = models.ForeignKey(Semester,db_index=True)
student = models.ForeignKey(CustomStudent, on_delete=CASCADE,db_index=True)
attendace = models.CharField(max_length = 20, choices=AttendenceChioces)
date = models.DateField(auto_now= True)
teacher = models.ForeignKey(settings.AUTH_USER_MODEL)#Dont call it #tname, explicit is better than implicit.
Also, I predict that there might be a situation where you will be asked to present the number of present days for a specific student in a specific semester. Something to think about.
I am a bit confused. You are capturing the data but where are you making the ajax POST? You need to share the POST request
var formData = new FormData()
$(document).ready(function(){
$("#checked").click('click', function(){
$students = document.getElementsByClassName('student-name').textContent;
$attendance = $('#attendance').val()
console.log($students)
console.log($attendance)
})
})
Shouldn't you be doing the following too
$.ajax({
type: "POST",
url: 'your url',
data: {
#your data
csrfmiddlewaretoken: csrf_token
},
success:function(response){
},
error:function(error){
}
});

Json Post from Django to Camunda

Further to my earlier post yesterday: Post request to external Rest Service using Django - use returned json to update model
I have managed to post data to camunda using Django - request.post. Using the following script:
payload = "{\n \"businessKey\": \"SomeValue\",\n \"variables\": {\n \"Organisation_ID\": {\n \"value\": \"SOmeUUID\",\n \"type\": \"String\"\n },\n \"UserID\": {\n \"value\":\"Some User ID\",\n \"type\": \"String\"\n }\n }\n}"
However when I start to use variables from the form and format my payload using
class StartProcessView(View):
template_name = 'startdeliveryphase.html'
def get(self,request, *args, **kwargs):
form = IntStartDeliveryPhase
return render(request, self.template_name,{'form':form})
def post(self,request, *args, **kwargs):
form = IntStartDeliveryPhase(request.POST or None)
if form.is_valid():
data = form.cleaned_data
OrganisationID = data['Form_Field_OrganisationID']
UserID = data['Form_Field_User_ID']
BusinessKey = data['Form_Field_Business_Key']
url = "http://localhost:8080/engine-rest/process-definition/key/Process_B_PerProject/start"
payload = {"businessKey":BusinessKey,"variables":[{"Organisation":[{"value":OrganisationID, "type":"String"}]},[{"Startedby":[{"value":UserID,"type":"String"}]}]]}
headers = {
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data = payload)
#print(repsonse.errors)
print(response.text.encode('utf8'))
return render(request)
else:
return render(request,self.template_name,{'form':form})
I get an error from the camunda engine:-
b'{"type":"JsonParseException","message":"Unrecognized token \'businessKey\': was expecting (\'true\', \'false\' or \'null\')\\n at [Source: (org.camunda.bpm.engine.rest.filter.EmptyBodyFilter$1$1); line: 1, column: 13]"}'
the local vars shows the following:
▼ Local vars
Variable Value
BusinessKey
'1qaz'
OrganisationID
<Organisation: Some Local Authoristy>
UserID
<Actor_User: me#me.com>
args
()
data
{'Form_Field_Business_Key': '1qaz',
'Form_Field_CamundaInstanceID': 'sss',
'Form_Field_Camunda_HRef': 'ss',
'Form_Field_Camunda_TenantID': '22',
'Form_Field_DateCreated': datetime.datetime(2020, 4, 23, 19, 22, 30, tzinfo=<StaticTzInfo 'GMT'>),
'Form_Field_OrganisationID': <Organisation: Some Local Authoristy>,
'Form_Field_User_ID': <Actor_User: me#me.com>}
form
<IntStartDeliveryPhase bound=True, valid=True, fields=(Form_Field_OrganisationID;Form_Field_DateCreated;Form_Field_CamundaInstanceID;Form_Field_Camunda_HRef;Form_Field_Camunda_TenantID;Form_Field_User_ID;Form_Field_Business_Key)>
headers
{'Content-Type': 'application/json'}
kwargs
{}
payload
{'businessKey': '1qaz',
'variables': [{'Organisation': [{'type': 'String',
'value': <Organisation: Some Local Authoristy>}]},
[{'Startedby': [{'type': 'String',
'value': <Actor_User: me#me.com>}]}]]}
request
<WSGIRequest: POST '/bimProcess/'>
response
<Response [400]>
self
<bimProcess.views.StartProcessView object at 0x055B7898>
url
'http://localhost:8080/engine-rest/process-definition/key/Process_B_PerProject/start'
How do I get the correct format as required by camunda into which I can insert my variables with the required double quotes
EDIT Yay - I have finally got the correct sequence!!!!
def post(self,request, *args, **kwargs):
form = IntStartDeliveryPhase(request.POST or None)
if form.is_valid():
data = form.cleaned_data
OrganisationID = str(data['Form_Field_OrganisationID'])
UserID = str(data['Form_Field_User_ID'])
BusinessKey = data['Form_Field_Business_Key']
url = "http://localhost:8080/engine-rest/process-definition/key/Process_B_PerProject/start"
payload = {"businessKey":BusinessKey,"variables":{"Organisation":{"value":OrganisationID, "type":"String"},"Startedby":{"value":UserID,"type":"String"}}}
headers = {
'Content-Type': 'application/json'
}
payload2 = json.dumps(payload)
print (payload2)
response = requests.request("POST", url, headers=headers, data=payload2)
#print(repsonse.errors)
print(response.text.encode('utf8'))
return render(request)
else:
return render(request,self.template_name,{'form':form})
Now for the next questions:
1) I get a response from Camunda as a 200: the payload back from the post request needs to go back into the form data where it can then be saved without user interruption.
2)I am doing a post self on this form - what is the best way of achieving the sequence flow? should I do a redirect and pass the data through or is there a more efficient way? Also is there a better way to achieve the view.py than I have posted which is more efficient?
def post(self,request, *args, **kwargs):
form = IntStartDeliveryPhase(request.POST or None)
if form.is_valid():
data = form.cleaned_data
OrganisationID = str(data['Form_Field_OrganisationID'])
UserID = str(data['Form_Field_User_ID'])
BusinessKey = data['Form_Field_Business_Key']
url = "http://localhost:8080/engine-rest/process-definition/key/Process_B_PerProject/start"
payload = {"businessKey":BusinessKey,"variables":{"Organisation":{"value":OrganisationID, "type":"String"},"Startedby":{"value":UserID,"type":"String"}}}
headers = {
'Content-Type': 'application/json'
}
payload2 = json.dumps(payload)
print (payload2)
response = requests.request("POST", url, headers=headers, data=payload2)
#print(repsonse.errors)
print(response.text.encode('utf8'))
return render(request)
else:
return render(request,self.template_name,{'form':form})

How to receive and save data via ajax in django?

through ajax I am sending the data correctly, because the data I see through wireshak and they are correct. On the django server, he sends me the correct request "POST / solit / HTTP / 1.1" 200 52. But the value sent does not receive it, it does not reach the Mysql database and I do not understand why, if the traffic sends well the data.
In wireshak I see the data of the post request, they are the correct ones, but they are not saved in the database, when I want them to be added as if I were to update the record of such database fields and it does not , I do not understand why
this is my views.py
def solit(request):
if request.method == 'POST' and request.is_ajax():
form = addiForm(request.POST)
if form.is_valid():
peticion = form.save(commit=False)
peticion.usuario = request.user
peticion.save()
peticion.usuario.d_pendientes = form.cleaned_data.POST.get('d_pendientes')
peticion.usuario.h_pendientes = form.cleaned_data.POST.get('h_pendientes')
peticion.usuario.save()
return JsonResponse({'status': 'true', 'msg': 'Procesado Correctamente'})
form = addiForm()
return render(request, 'plantillas/adicionar.html', {'form':form})
This is my models.py------------------------------
class Usuarios(AbstractUser):
numero_empleado = models.IntegerField(null= True, blank= True)
area = models.CharField(max_length = 200, null= True, blank= True)
d_pendientes = models.IntegerField(null= True, blank= False)
h_pendientes = models.IntegerField(null= True, blank= False)
f_init = models.DateField(max_length = 200,null= True, blank= True)
init_vac = models.DateField(max_length = 200, null= True, blank= True)
fin_vac = models.DateField(max_length = 200, null= True, blank= True)
ul_vac_tomadas = models.IntegerField(null= True, blank= True)
class Peticion(models.Model):
solit_choices = (
('Adicionar','Adicionar'),
)
solicitudes_id = models.AutoField(primary_key=True)
usuario = models.ForeignKey(Usuarios, on_delete=models.CASCADE, null=True, blank=True)
petit = models.CharField(max_length = 255, choices=solit_choices, null=True, blank=False)
fec = models.DateTimeField(auto_now=True)
razon = models.TextField(max_length=255, null=True, blank=True)
periodo_init = models.DateField(max_length = 200, null=True, blank=True)
periodo_fin = models.DateField(max_length = 200, null=True, blank=True)
dias_adicion = models.IntegerField(null=True, blank=False)
horas_adicion = models.FloatField(null=True, blank=False)
this is my forms.py
class addiForm(forms.ModelForm):
class Meta:
"""Formulario de solicitud"""
model = Peticion
fields = [
'solicitudes_id',
'petit',
'razon',
'periodo_init',
'periodo_fin',
'dias_adicion',
'horas_adicion',
]
labels = {
'solicitud_id':'Solicitud',
'petit':'Tipo de Petición',
'razon':'Razon',
'periodo_init':'Rango de fecha inicial',
'periodo_fin':'Fecha final',
'dias_adicion':'Dias a adicionar, si es mas de 8 horas',
'horas_adicion':'Horas a adiciona, si es menos de 1 dia',
html file
{% extends "plantillas/base.html" %}
{% block content %}
{% load staticfiles %}
{% now "Y-m-d H:i:s" %} <br>
{{ user.Peti}}
{{ user.numero_empleado}}
<script src="{% static 'js/int.js'%}"></script>
<script
src="https://code.jquery.com/jquery-3.4.1.js"
integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU="
crossorigin="anonymous"></script>
<div><form method="POST" id="demo" class="form-data" action="{% url 'solit' %}">
{% csrf_token %}
<h6>Tipo de peticion:{{form.petit}}</h6>
<h6>Razon:{{form.razon}}</h6>
<h6>{{form.solicitudes_id}}</h6>
<h6>Fecha inicio:{{form.periodo_init}}</h6>
<h6>Fecha fin:{{form.periodo_fin}}</h6>
<h6>Introduzca dias a tomar<input id="dias" type="number" name="dias_adicion"></h6>
<h6>Introduzca horas a tomar<input id="horas" type="number" name="horas_adicion"></h6>
<input type="hidden" id="const_dias" name="d_pendientes" value="{{ user.d_pendientes }}">
<input type="hidden" id="const_horas" name="h_pendientes" value="{{ user.h_pendientes }}">
<button type="submit" onclick="calculo()">Guardar</button>
</div></form></span>
<h6>Recuerde, que usted dispone de {{ user.d_pendientes }} dias y {{ user.h_pendientes }} horas</h6>
js file---------------------
function calculo()
{
var dias = parseInt(document.getElementById('dias').value);
var horas = parseFloat(document.getElementById('horas').value);
var dias_base = parseInt(document.getElementById('const_dias').value);
var horas_base = parseFloat(document.getElementById('const_horas').value);
dias_base -= dias;
horas_base -= horas;
document.getElementById('const_dias').value = dias_base;
document.getElementById('const_horas').value = horas_base;
} console.log(calculo);
server django console [24/Jul/2019 15:30:47] "POST /solit/ HTTP/1.1" 200 52 and the js console msg: "Procesado Correctamente"
status: "true"
ajax script--------------------------------------------
$(document).ready(function(calculo){
var productForm = $("#demo")
productForm.submit(function(event){
event.preventDefault();
var thisForm = $(this)
var actionEndpoint = thisForm.attr("action");
var httpMethod = thisForm.attr("method");
var formData = thisForm.serialize();
$.ajax({
url: actionEndpoint,
method: httpMethod,
data: formData,
success: function(data){
console.log("success")
console.log(data)
},
error: function(erroData){
console.log("error")
console.log(erroData)
}
})
})
})
You still haven't really explained where you want the value for "usario" to come from. I'm going to assume that you want it to be the currently logged-in user. In which case, you can do this:
form = addiForm(request.POST)
if form.is_valid():
peticion = form.save(commit=False)
peticion.usuario = request.user
peticion.save()
peticion.usuario.d_pendientes = form.cleaned_data.get('d_pendientes')
peticion.usuario.h_pendientes = form.cleaned_data.get('h_pendientes')
peticion.usuario.save()
return JsonResponse({'status': 'true', 'msg': 'Procesado Correctamente'})
(Note, .get is a method, it needs parentheses not square brackets. And None is the default, you don't need to specify it explicitly.)
Edit
I'm finding it really hard to understand what you are asking, but I think your problem is that you simply don't have anything in the form called dias_adicionar or horas_adicionar; they are called d_pendientes and h_pendientes in line with your actual field names.
There isn't anything in your JavaScript code which makes an AJAX request - it's just a normal form POST request. This means request.is_ajax() will be false, and the form saving code doesn't execute.

Why CRUD Operations Using Ajax and Json for Django powered app is so slow?If being 7000 records is an issue, how can I improve it to seconds?

I am performing operations on remote legacy MySQL database having about 7000 records.Currently, it's taking around 1.5 minutes for the Update / Delete / Create operation.I have also imported necessary files which is not included in Views.py below.
Is using dict() a problem? Should I use Rest? OR some other API. Any suggestions will be appreciated!
Here is the code:
plugin.js
$(document).ready(function(){
var ShowForm = function(){
var btn = $(this);
$.ajax({
url: btn.attr("data-url"),
type: 'get',
dataType:'json',
beforeSend: function(){
$('#modal-book').modal('show');
},
success: function(data){
$('#modal-book .modal-content').html(data.html_form);
}
});
};
var SaveForm = function(){
var form = $(this);
$.ajax({
url: form.attr('data-url'),
data: form.serialize(),
type: form.attr('method'),
dataType: 'json',
success: function(data){
if(data.form_is_valid){
$('#book-table tbody').html(data.book_list);
$('#modal-book').modal('hide');
} else {
$('#modal-book .modal-content').html(data.html_form)
}
}
})
return false;
}
// create
$(".show-form").click(ShowForm);
$("#modal-book").on("submit",".create-form",SaveForm);
//update
$('#book-table').on("click",".show-form-update",ShowForm);
$('#modal-book').on("submit",".update-form",SaveForm)
//delete
$('#book-table').on("click",".show-form-delete",ShowForm);
$('#modal-book').on("submit",".delete-form",SaveForm)
});
Views.py
# Fetching records with pagination
#login_required()
def book_list(request):
books = AvailstaticCopy.objects.all().order_by('-row_date')
page = request.GET.get('page', 1)
paginator = Paginator(books, 144)
try:
books = paginator.page(page)
except PageNotAnInteger:
books = paginator.page(1)
except EmptyPage:
books = paginator.page(paginator.num_pages)
context = {
'books': books
}
return render(request, 'books/book_list.html',context)
#login_required()
def save_all(request,form,template_name):
data = dict()
if request.method == 'POST':
if form.is_valid():
form.save()
data['form_is_valid'] = True
books = AvailstaticCopy.objects.all()
data['book_list'] = render_to_string('books/book_list_2.html',
{'books':books})
else:
data['form_is_valid'] = False
context = {
'form':form
}
data['html_form'] = render_to_string(template_name,context,request=request)
return JsonResponse(data)
# Create new record
#login_required()
def book_create(request):
if request.method == 'POST':
form = AvailForm(request.POST)
else:
form = AvailForm()
return save_all(request,form,'books/book_create.html')
# Update record
#login_required()
def book_update(request,id):
book = get_object_or_404(AvailstaticCopy,id=id)
if request.method == 'POST':
form = AvailForm(request.POST,instance=book)
else:
form = AvailForm(instance=book)
return save_all(request,form,'books/book_update.html')
# Delete Record
#login_required()
def book_delete(request,id):
data = dict()
book = get_object_or_404(AvailstaticCopy,id=id)
if request.method == "POST":
book.delete()
data['form_is_valid'] = True
books = AvailstaticCopy.objects.all()
data['book_list'] = render_to_string('books/book_list_2.html',
{'books':books})
else:
context = {'book':book}
data['html_form'] =
render_to_string('books/book_delete.html',context,request=request)
return JsonResponse(data)
I suppose, your problem is in server responses. In all views where you change server data (delete, update, create) you try return updated book list, but you do not paginate book queryset, and django template processor take a lot of time to prepare html with all books. I suggest you add function which will paginate queryset like this:
def get_book_page(request, books):
page = request.GET.get('page', 1)
paginator = Paginator(books, 144)
try:
books = paginator.page(page)
except PageNotAnInteger:
books = paginator.page(1)
except EmptyPage:
books = paginator.page(paginator.num_pages)
return books
And wrap all book querysets in your views. Also it will be needed add to urls page number as get parameter (for example /update-book/1?page=2) because if you don't do it, it won't be work.
Thanks for giving me a hint.That worked! I have paginated queryset like this:
def save_all(request,form,template_name):
data = dict()
paginate_by = 144
if request.method == 'POST':
if form.is_valid():
form.save()
data['form_is_valid'] = True
books = AvailstaticCopy.objects.all().order_by('-row_date')
page = request.GET.get('page', 1)
paginator = Paginator(books, 144)
try:
books = paginator.page(page)
except PageNotAnInteger:
books = paginator.page(1)
except EmptyPage:
books = paginator.page(paginator.num_pages)
data['book_list'] = render_to_string('books/book_list_2.html',
{'books':books})
else:
data['form_is_valid'] = False
context = {
'form':form
}
data['html_form'] = render_to_string(template_name,context,request=request)
return JsonResponse(data)