I have a long python function and within the function I am generating a voucher which I would want to autofill in my HTML page. Kindly assist
The full function:
def confirmation(request):
print("Start MpesaCallback")
global profile
mpesa_body = request.body.decode('utf-8')
mpesa_body = json.loads(mpesa_body)
print(mpesa_body)
print("Mpesa Body")
merchant_requestID = mpesa_body["Body"]["stkCallback"]["MerchantRequestID"]
print('merchant_requestID: ', merchant_requestID)
checkout_requestID = mpesa_body["Body"]["stkCallback"]["CheckoutRequestID"]
print('checkout_requestID: ', checkout_requestID)
result_code = mpesa_body["Body"]["stkCallback"]["ResultCode"]
print('result_code: ', result_code)
result_desc = mpesa_body["Body"]["stkCallback"]["ResultDesc"]
print('result_desc: ', result_desc)
metadata = mpesa_body["Body"]["stkCallback"]["CallbackMetadata"]["Item"]
for item in metadata:
title = item["Name"]
if title == "Amount":
amount = item["Value"]
print('Amount: ', amount)
elif title == "MpesaReceiptNumber":
mpesa_receipt_number = item["Value"]
print('Mpesa Reference No: ', mpesa_receipt_number)
elif title == "TransactionDate":
transaction_date = item["Value"]
print('Transaction date: ', transaction_date)
elif title == "PhoneNumber":
phone_number = item["Value"]
print('Phone Number: ', phone_number)
str_transaction_date = str(transaction_date)
trans_datetime = datetime.strptime(str_transaction_date, "%Y%m%d%H%M%S")
tz_trans_datetime = pytz.utc.localize(trans_datetime)
payment = MpesaPayment.objects.create(
MerchantRequestID=merchant_requestID,
CheckoutRequestID=checkout_requestID,
ResultCode=result_code,
ResultDesc=result_desc,
Amount=amount,
MpesaReceiptNumber=mpesa_receipt_number,
TransactionDate=tz_trans_datetime,
PhoneNumber=phone_number,
)
if result_code == 0:
payment.save()
print("Successfully saved")
password_length = 5
voucher = secrets.token_urlsafe(password_length)
print(voucher)
headers = {
'Content-Type': 'application/json',
'h_api_key': os.getenv("SMS_Token"),
'Accept': 'application/json'
}
payload = {
"mobile": phone_number,
"response_type": "json",
"sender_name": "23107",
"service_id": 0,
"message": "Your WiFi Voucher is " + voucher + ".\nAirRumi."
}
response = requests.request("POST", 'https://smsdomain.com/sms/sendsms', headers=headers,
json=payload)
r = response.json()
print(r)
print("SMS Sent")
print(amount)
if amount == 1:
profile = 'one_hour'
elif amount == 50:
profile = 'one_day'
elif amount == 300:
profile = 'one_week'
elif amount == 1000:
profile = 'one_month'
else:
print('Incorrect Amount')
print(profile)
connection = routeros_api.RouterOsApiPool(
host=os.getenv("ip"),
username=os.getenv("usernamee"),
password=os.getenv("password"),
port=8728,
use_ssl=False,
ssl_verify=False,
ssl_verify_hostname=True,
ssl_context=None,
plaintext_login=True
)
api = connection.get_api()
user = api.get_resource('/ip/hotspot/user')
user.add(name=voucher, server="hotspot1", password='1234', profile=profile)
print("User " + voucher + " created.")
else:
print("Payment was not successful")
context = {
"resultcode": result_code,
"resultdesc": result_desc
}
if context['resultcode'] == 0:
return JsonResponse(dict(context))
My HTML page that I want auto filled:
<form name="login" action="http://mydomain/login" method="post">
{% csrf_token %}
<input type="hidden" name="dst" value="https://www.google.com"/>
<input type="hidden" name="popup" value="true"/>
<label>
<input type="text" name="username" value="{{ voucher }}" placeholder="Enter your Voucher" required>
</label>
<label>
<input type="hidden" name="password" value="1234">
</label><br><br>
<div id="login-button"><input type="submit" value="CONNECT"/></div>
</form>
How do I get the voucher generated and auto fill it in the HTML? I have used the {{ voucher }} and its not working.
I have updated the whole function but not the whole view.py
You can use render for django.shortcuts module:
from django.shortcuts import render
def confirmation(request):
# Your code here
...
context = {
"resultcode": result_code,
"resultdesc": result_desc,
"voucher": voucher, # <- HERE
}
# Comment
# if context['resultcode'] == 0:
# return JsonResponse(dict(context))
return render(request, 'your_template.html', context=context)
Related
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){
}
});
I want to add description text from users profile page to description column in my database, but when I submit form nothing happens and this column still empty.
I can get id and email on profile page after login, but can not get description form to my profile method
This is my database structure
login method:
#app.route('/', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
email = request.form['email']
password = request.form['password']
cur = mysql.connection.cursor()
cur.execute('SELECT * FROM users.data WHERE email = %s AND password = %s',
(email, password))
account = cur.fetchone()
if account:
session['loggedin'] = True
session['id'] = account[0]
session['email'] = account[3]
return redirect(url_for('profile'))
else:
return render_template('error.html')
return render_template('login.html')
profile method:
#app.route('/profile', methods=['GET','POST'])
def profile():
if 'loggedin' in session:
return render_template('profile.html', id=session['id'], email=session['email'])
if request.method == 'POST':
description = request.form['text']
cur = mysql.connection.cursor()
cur.execute('UPDATE users.data SET description = %s WHERE id = ?', (description, session['id']))
mysql.connection.commit()
cur.close()
return render_template('profile.html', id=session['id'], email=session['email'], description=description)
else:
return 'NO'
return redirect(url_for('login'))
profile.html:
your session id is: {{ id }}
your session email is: {{ email }}
your session symptom is: {{ description }}
<form action="" method="post">
<input type="text" name="text" class="form-control" placeholder="description">
<button class="btn btn-primary">Add</button>
</form>
Please assist.
I found an answer:
#app.route('/profile', methods=['GET','POST'])
def profile():
if request.method == 'GET':
if 'loggedin' in session:
return render_template('profile.html', id=session['id'], email=session['email'])
elif request.method == 'POST':
description = request.form['description']
print(description)
cur = mysql.connection.cursor()
# cur.execute('INSERT INTO users.data(description) VALUES (%s)', (description))
cur.execute('UPDATE users.data SET description = %s WHERE id = %s', (description, session['id']))
mysql.connection.commit()
cur.close()
print(description)
return render_template('profile.html', description=description)
else:
return 'NO'
return redirect(url_for('login'))
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)
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.
I have a django model which contains some fields with associated choices:
class Product(models.Model):
CONDITION_CHOICES = (
("GOOD", "Good"),
("BAD", "Bad"),
("UNKNOWN", "Unknown"),
)
name = models.CharField(max_length=200, blank=True, null=True)
colour = models.CharField(max_length=200, blank=True, null=True)
condition = models.CharField(max_length=20, choices=CONDITION_CHOICES, blank=True, null=True)
condition_source = models.CharField(max_length=20, blank=True, null=True)
condition_last_updated = models.DateTimeField(blank=True, null=True)
I also have a bootstrap driven form that looks like:
<div class="form-group">
<label class="control-label"><strong>Condition</strong></label>
<br/>
<div class="btn-group btn-group-toggle" data-toggle="buttons">
<label class="btn btn-outline-primary">
<input type="radio" name="condition" value="GOOD" autocomplete="off">
Good
</label>
<label class="btn btn-outline-primary">
<input type="radio" name="condition" value="BAD" autocomplete="off">
Bad
</label>
<label class="btn btn-outline-primary">
<input type="radio" name="condition" value="UNKNOWN" autocomplete="off">
Unknown
</label>
</div>
</div>
I am trying to make it so that when a user clicks on one of the buttons in the UI, the Product model is updated (specifically the condition, condition_source and condition_last_updated fields). The actual model has multiple fields with associated with choice options so I'd like the model to get updated in real time without a page reload as a user works through the form.
Any guidance would be appreciated here - I have looked at intercooler.js but unsure if this is the right tool for the job.
As you have not specified what condition_source should include I have set it to string some_source
Ajax:
$('.btn').on('click', function(){
$.post(
'/your_vew/',
{
'source': "some_source",
'condition': $(this).find('input').val(),
'csrfmiddlewaretoken': '{{csrf_token}}'
},
function(data){
console.log(data.response);
}
);
});
urls.py:
urlpatterns = [
...
path('your_vew/', views.your_view),
...
]
views.py:
from django.http import JsonResponse
from datetime import datetime
def your_view(request):
data = {'response': ''}
if request.method == 'POST':
p1 = Product.objects.filter(pk=1).update(
condition_source=request.POST.get('source'),
condition=request.POST.get('condition'),
condition_last_updated=datetime.now()
)
if p1:
data['response'] = 'Record updated!'
return JsonResponse(data)
Now, you have a few options. What I did is that i used the Jquery ajax method in form of a class and set up my functions for my applications inside this class. Django requires the csrf token in order to process incomming requests. So i found these two functions which retreives the cookie csrf token from the client.
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
Once the csrf token has been stored in a variable you need to pass this to the ajax beforeSend function for example like this:
ajax_setup(enable_async){
enable_async = true;
$.ajaxSetup({
async: enable_async,
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
}
}
});
}
}
The full ajax request would be something like
update_user_language(user_id, lang, callback){
this.ajax_setup(true);
$.ajax({
url: this.url,
type: "POST",
data: {
'user_id':user_id,
'lang':lang,
},
dataType: 'json',
success: function(data){
db_request_after();
if(callback !== undefined) callback(data);
},
error: function(){
db_request_error();
},
});
}
Note the callback variable. This allows ajax to call a function passing the data retreived from the webservice.
Once you sent the request you need to setup your view.py to accept the request and process the POST variables.
def sample_view(request):
if request.method == "POST"
user_id = request.POST.get('user_id')
lang = request.POST.get('lang')
#update the model value
user = User.objects.get(pk=user_id)
user.language = lang
user.save()
return JsonResponse({'message':'user updated'})
else:
return render(...)