This is Error showing
TypeError at /page
Field 'mobile' expected a number but got ['22222', '3333'].
Request Method: POST
Request URL: http://127.0.0.1:8000/page
Django Version: 4.1
Exception Type: TypeError
Exception Value:
Field 'mobile' expected a number but got ['22222', '3333'].
While Submitting Form This error occurs. I am trying to submit form of same name twice simultaneously to same model
Views.py
def page(request):
if request.method == 'POST':
description = request.POST['description']
price = request.POST['price']
name = request.POST.getlist('name')
mobile = request.POST.getlist('mobile')
pay = bill(description=description,price=price)
pay.save()
mypayee = payee(billId=pay,name=name,mobile=mobile)
mypayee.save()
return render(request, 'split_app/page.html')
this model
from django.db import models
# Create your models here.
class bill(models.Model):
price = models.IntegerField()
description = models.CharField(max_length=200)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.description
class payee(models.Model):
billId = models.ForeignKey(bill,on_delete=models.CASCADE,related_name='persons')
name = models.CharField(max_length=50)
mobile = models.IntegerField()
this is image of HTML FORM generated using javascript enter image description here
** This is how I am submitting data with form having same form twice of same name(name & mobile) **
HTML generate
<div >
<button type="button" >ADD NEW BILL</button>
<form action="/page" method="POST">
{% csrf_token %}
<div >
<label for="discription" >DESCRIPTION:</label>
<div >
<input type="text" name="description" id="discription" placeholder="Bill For.." />
</div>
</div>
<div >
<label for="price" >BILL PRICE:</label>
<div >
<input type="number" name="price" id="price" title="only numbers allowed"
placeholder="₹" />
</div>
</div>
<div >
<label for="person" >SPLIT IN:</label>
<div >
<button type="button" onclick="increment()"> </button>
<button type="button" id="payeesbtn">ADD PAYEE:</button>
<button type="button" onclick="decrement()">-</button>
<div id="addpayees"></div>
</div>
</div>
<button type="submit" >Save</button>
</form>
</div>
Javascript
let x = 1;
function increment() {
const div = document.createElement('div');
div.className = 'container my-3';
div.idName = 'x';
div.innerHTML = `<h5>payee ${x}</h5>
<table>
<tr>
<th>Name:</th>
<td><input type="text" name="name"></td>
</tr>
<tr>
<th>Mobile:</th>
<td><input type="number" name="mobile"></td>
</tr>
</table>
<input type="button" value="-" onclick="decrement(this)" />
<button type="button" onclick="decrement(this)">-</button>`;
document.getElementById("addpayees").appendChild(div);
x ;
};
CodePudding user response:
The payee.mobile
field is defined as an IntegerField
, but in your view function you are calling:
mobile = request.POST.getlist('mobile')
which produces a list of values. Then you do this:
mypayee = payee(billId=pay,name=name,mobile=mobile)
That is what the error tells you. You are trying to create a payee
instance and assign a list to the integer field.
PS:
If you want to create two separate instances of payee
with both those values ['22222', '3333']
, you need to do something like:
mypayee1 = payee(billId=pay,name=int(name[0]),mobile=int(mobile[0]))
mypayee2 = payee(billId=pay,name=int(name[1]),mobile=int(mobile[1]))
But I am just guessing here.
PPS:
If the size of the name
and mobile
lists is dynamic, you could loop over them. You did not provide a lot of context, but I assume that those query parameters in the POST
request will have the same number of items, i.e. the lists will be of the same size. Then you could do something like this:
def page(request):
...
names = request.POST.getlist('name')
mobiles = request.POST.getlist('mobile')
pay = bill(description=description,price=price)
pay.save()
for name, mobile in zip(names, mobiles):
mypayee = payee(billId=pay,name=name,mobile=int(mobile))
mypayee.save()
If you don't care about the pre_save
and post_save
signals, you could create them in bulk like this: (check the docs for caveats!)
def page(request):
...
names = request.POST.getlist('name')
mobiles = request.POST.getlist('mobile')
pay = bill(description=description,price=price)
pay.save()
payee.objects.bulk_create([
payee(billId=pay,name=name,mobile=int(mobile))
for name, mobile in zip(names, mobiles)
])
Either way, at this point I would strongly suggest wrapping the entire affair in a transaction to ensure data integrity.