Django: невозможно распаковать не повторяемый объект int - PullRequest
1 голос
/ 08 апреля 2020

я учусь django и Python. У меня проблема с формой.

ошибка "TypeError at / My_app" и "не удается распаковать не повторяемый объект int"

это мои представления:

from django.http import HttpResponse, Http404
from django.shortcuts import redirect, render, get_object_or_404
from datetime import datetime

from Qualite.forms import NCForm
from Qualite.models import NC, Nc_type, Poste

def view_accueil(request):

    form = NCForm(request.POST or None)

    if form.is_valid():
        newNc = NC()
        newNc.idaffaire = form.cleaned_data['idaffaire']
        newNc.idnc = form.cleaned_data['idnc']
        newNc.idof = form.cleaned_data['idof']
        newNc.idposte = form.cleaned_data['idposte']
        newNc.idrepere = form.cleaned_data['idrepere']
        newNc.iquantite = form.cleaned_data['iquantite']
        newNc.save()

    return render(request, 'Qualite/accueil.html', locals())

мои формы:

from django import forms
from .models import Nc_type, NC, Poste

class NCForm(forms.Form):

    #choices = NC.objects.values_list('id', 'idaffaire')
    ncs = NC.objects.values_list('idaffaire', flat = True)

    idaffaire = forms.ChoiceField(choices = (ncs))
    idof = forms.CharField()
    idrepere = forms.CharField()
    idposte = forms.CharField()
    idnc = forms.CharField()
    quantite = forms.CharField()

и моя модель

from django.db import models
from django.utils import timezone

class Nc_type(models.Model):
    nom = models.CharField(max_length=30)

    def __str__(self):
        return self.nom

class Poste(models.Model):
    nom = models.CharField(max_length=50)

    def __str__(self):
        return self.nom


class NC(models.Model):
    idaffaire = models.CharField(max_length=4, db_column='idAffaire')
    idof = models.IntegerField(db_column='idOf')
    idposte = models.ForeignKey('Poste', models.DO_NOTHING, db_column="idPoste", default=1)
    idrepere = models.IntegerField(db_column='idRepere')
    idnc = models.ForeignKey(Nc_type, models.DO_NOTHING, db_column='idNc_type', default=1)
    quantite = models.PositiveIntegerField()
    dateajout = models.DateTimeField(default=timezone.now, db_column='dateAjout')

и шаблон:

<h1>Ajout d'une NC</h1>

<form action="{% url "accueil" %}" method="GET">
    {% csrf_token %}
    {{ form }}
    <input type="submit" value="Submit" />
</form>

это кто-то, чтобы помочь мне понять проблему , Я искал решение в сети, но никак не мог.

Ответы [ 2 ]

0 голосов
/ 09 апреля 2020

Спасибо за ответ. Так лучше У меня есть только еще один вопрос. Я не понимаю ваш ответ о перенаправлении и шаблоне Get. Фактически, когда я отправил форму, я получил ошибку вроде: NoReverseMatch

0 голосов
/ 08 апреля 2020

Проблема в том, что запрос типа:

ncs = NC.objects.values_list('idaffaire', flat=True)

приведет к тому, что ncs будет целым числом int объектов. Но для choices из ChoiceField требуется список 2-кортежей с ключом в качестве первого элемента этих 2-кортежей и меткой в ​​качестве второго элемента из 2-кортежей.

Тем не менее, использование запроса на уровне класса не хорошая идея. Это означает, что запрос будет выполнен с загруженным классом. Это означает, что если вы позже добавите дополнительный NC объект, форма не предложит его в качестве нового выбора.

Я бы также посоветовал использовать ModelForm [Django -doc] вместо этого, поскольку это приведет к удалению большого количества стандартного кода, особенно потому, что, например, idposte необходимо использовать допустимое значение для объекта Poste, и здесь ваша форма не может подтвердите это.

Затем вы можете реализовать форму следующим образом:

from django import forms
from .models import NC

class NCForm(forms<b>.ModelForm</b>):
    class Meta:
        model = NC
        fields = '__all__'

Затем в вашем views.py вы можете использовать эту форму с:

from django.shortcuts import redirect

def view_accueil(request):
    if request.method == 'POST':
        form = NCForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect(<i>'name-of-a-view'</i>)
    else:
        form = NCForm()
    return render(request, 'Qualite/accueil.html', {'form': form})

Примечание : В случае успешного запроса POST вы должны сделать redirect [Django -doc] для реализации Post / Redirect / Get pattern [wiki] . Это позволяет избежать того же запроса POST, когда пользователь обновляет браузер.

...