Home > Software engineering >  Field 'mobile' expected a number but got ['2222222', '2222222']
Field 'mobile' expected a number but got ['2222222', '2222222']

Time:08-24

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="&#x20B9" />
                </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.

  • Related