Reputation: 5
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 class="container my-3">
<button type="button" class="btn btn-secondary">ADD NEW BILL</button>
<form action="/page" method="POST">
{% csrf_token %}
<div class="input-group mb-3">
<label for="discription" class="col-sm-2 col-form-label">DESCRIPTION:</label>
<div class="col-sm-2">
<input type="text" name="description" id="discription" placeholder="Bill For.." />
</div>
</div>
<div class="input-group mb-3">
<label for="price" class="col-sm-2 col-form-label">BILL PRICE:</label>
<div class="col-sm-2">
<input type="number" name="price" id="price" title="only numbers allowed"
placeholder="₹" />
</div>
</div>
<div class="mb-3 row">
<label for="person" class="col-sm-2 col-form-label">SPLIT IN:</label>
<div class="col-sm-10">
<button type="button" class="btn btn-info" onclick="increment()">+</button>
<button type="button" class="btn btn-info" id="payeesbtn">ADD PAYEE:</button>
<button type="button" class="btn btn-info" onclick="decrement()">-</button>
<div class="container my-3" id="addpayees"></div>
</div>
</div>
<button type="submit" class="btn btn-info">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" class="btn btn-info" onclick="decrement(this)">-</button>`;
document.getElementById("addpayees").appendChild(div);
x++;
};
Upvotes: 0
Views: 83
Reputation: 18663
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.
Upvotes: 2