Поле 'mobile' ожидало число, но получило ['2222222', '2222222'].

Появляется ошибка

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'].

Во время отправки формы возникает эта ошибка. Я пытаюсь отправить одноименную форму дважды одновременно в одну и ту же модель

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')

эта модель

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()

это изображение HTML FORM, сгенерированное с помощью javascript. введите здесь описание изображения

** Вот как я отправляю данные с помощью формы, имеющей одну и ту же форму дважды с одинаковым именем (имя и мобильный) **

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="&#x20B9" />
                </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++;
};

Поле payee.mobile определено как IntegerField, но в вашей функции представления вы вызываете:

mobile = request.POST.getlist('mobile')

, который выдает список значений. Затем вы делаете следующее:

mypayee = payee(billId=pay,name=name,mobile=mobile)

Об этом вам говорит ошибка. Вы пытаетесь создать экземпляр payee и присвоить список целочисленному полю.

PS:

Если вы хотите создать два отдельных экземпляра payee с обоими значениями ['22222', '3333'], вам нужно сделать что-то вроде:

mypayee1 = payee(billId=pay,name=int(name[0]),mobile=int(mobile[0]))
mypayee2 = payee(billId=pay,name=int(name[1]),mobile=int(mobile[1]))

Но я только предполагаю.

PPS:

Если размер списков name и mobile динамический, вы могли бы перебирать их в цикле. Вы не предоставили много контекста, но я предполагаю, что эти параметры запроса в запросе POST будут иметь одинаковое количество элементов, т.е. списки будут одинакового размера. Тогда вы могли бы сделать что-то вроде этого:

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()

Если вам не важны сигналы pre_save и post_save, вы можете создать их массово следующим образом: (проверьте документацию на предмет предостережений!)

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)
    ])

В любом случае, на данном этапе я бы настоятельно рекомендовал завернуть все это дело в транзакцию для обеспечения целостности данных.

Вернуться на верх