Python Django ошибка "Выберите правильный выбор. Этот выбор не является одним из доступных вариантов".

Я относительно новичок в Django, поэтому, скорее всего, я делаю что-то явно неправильно, но я не могу понять, что именно. У меня есть модель под названием Report, которая имеет ряд полей, включая связь по внешнему ключу с моей моделью Plot. В форме модели Report у меня есть дополнительные поля, которые не являются частью модели, но используются для фильтрации/поиска нужного участка. Я использую javascript для получения этих значений при изменении соответствующего поля.

Сначала пользователь выбирает застройщика из списка (он настроен как поле ModelChoice и заполняется при инициализации с помощью набора запросов), затем появляется список объектов, принадлежащих застройщику, затем он выбирает нужный объект, в результате появляются все участки, которые являются частью этого объекта, и, наконец, он выбирает нужный участок. Когда форма отправлена, я получаю сообщение "Выберите правильный вариант". 37d86254-29c5-456d-8264-f47e893ae789 не является одним из доступных вариантов." для полей development и plot_id.

Моя цель - использовать значение plot_id (plot pkid) для получения экземпляра соответствующего сюжета в представлении и сохранить его во внешней ключевой связи report.plot в соответствии с моделью. Я делаю это таким образом, потому что не верю, что можно получить набор запросов через javscript fetch и заполнить форму этими значениями динамически. Любая помощь / совет будут с благодарностью приняты.

Форма отчета -

class CreateSnagReportForm(ModelForm):
    class Meta:
        model = Report
        exclude = (
            "developer",
            "development",
            "plot_id",
            "created",
            "id",
            "active",
            "accepted",
        )
        widgets = {
            "description": forms.TextInput(
                attrs={
                    "class": "form-control",
                    "placeholder": "Plot & Development",
                }
            ),
            "customer_name": forms.TextInput(
                attrs={"class": "form-control", "placeholder": "Customer Name"}
            ),
            "customer_email": forms.TextInput(
                attrs={"class": "form-control", "placeholder": "Customer Email"}
            ),
            "customer_service_name": forms.TextInput(
                attrs={
                    "class": "form-control",
                    "placeholder": "Customer Service Contact Name",
                }
            ),
            "customer_service_email": forms.TextInput(
                attrs={
                    "class": "form-control",
                    "placeholder": "Customer Service Contact Email",
                }
            ),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.fields["developer"] = forms.ModelChoiceField(
            queryset=DeveloperOrg.objects.filter(development__isnull=False)
            .distinct()
            .order_by("name"),
            required=True,
            widget=forms.Select(
                attrs={
                    "class": "form-select",
                    "placeholder": "Developer",
                    "id": "developerName",
                    "onchange": "selectDevelopment()",
                }
            ),
        )
        self.fields["development"] = forms.ChoiceField(
            widget=forms.Select(
                attrs={
                    "class": "form-select",
                    "placeholder": "Select Development",
                    "id": "developmentName",
                    "onchange": "selectPlot()",
                }
            ),
        )
        self.fields["plot_id"] = forms.ChoiceField(
            widget=forms.Select(
                attrs={
                    "class": "form-select",
                    "placeholder": "Select Plot",
                    "id": "plotNumber",
                }
            ),
        )

Модель отчета -

class Report(models.Model):
    description = models.CharField(max_length=500, blank=False, null=False)
    customer_name = models.CharField(
        max_length=200, unique=False, blank=True, null=True
    )
    customer_email = models.EmailField(
        _("email address"),
        unique=False,
        blank=True,
        null=True,
        validators=[EmailValidator],
    )
    customer_service_name = models.CharField(
        max_length=200, unique=False, blank=True, null=True
    )
    customer_service_email = models.EmailField(
        _("email address"),
        unique=False,
        blank=True,
        null=True,
        validators=[EmailValidator],
    )
    plot = models.ForeignKey(Plot, null=True, blank=True, on_delete=models.SET_NULL)
    created = models.DateTimeField(auto_now_add=True)
    id = models.UUIDField(
        default=uuid.uuid4, unique=True, primary_key=True, editable=False
    )
    active = models.BooleanField(default=True)
    accepted = models.BooleanField(default=False)

    def __str__(self):
        return self.description

Создать вид отчета -

def create_snag_report(request):
    form = CreateSnagReportForm()
    if request.method == "POST":
        form = CreateSnagReportForm(request.POST)
        if request.POST.get("plot_id"):
            plot = get_object_or_404(Plot, pk=request.POST["plot_id"])
            if form.is_valid():
                report = form.save(instance=plot)
                report.save()
                return redirect("list-snags-for-plot")
            print(form.errors)
            print(request.POST)
    context = {"form": form}
    return render(request, "snagging/create_snag_report.html", context)

Ок, мне удалось разобраться с проблемой, и оказалось, что выбор полей в development и plot if требовал список кортежей, а я передавал одну строку (pkid).

Вот обновленный код представления.

def create_snag_report(request):
    form = CreateSnagReportForm()
    if request.method == "POST":
        form = CreateSnagReportForm(request.POST)
        plot_id = request.POST.get("plot_id")
        development_id = request.POST.get("development")
        if development_id and plot_id:
            form.fields["development"].choices = [(development_id, development_id)]
            form.fields["plot_id"].choices = [(plot_id, plot_id)]
            plot = get_object_or_404(Plot, pk=plot_id)
            if form.is_valid():
                print("valid")
                report = form.save(commit=False)
                report.plot = plot
                report.save()
                return redirect("list-snags-for-plot")
            print(form.errors)
            print(request.POST)
    context = {"form": form}
    return render(request, "snagging/create_snag_report.html", context)

Поскольку эти поля требуются только для фильтрации, я полагаю, что могу просто удалить их из формы перед валидацией?

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