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)
Поскольку эти поля требуются только для фильтрации, я полагаю, что могу просто удалить их из формы перед валидацией?