Django ModelChoiceField передает None
Я очень новичок в Django.
Я делаю форму для добавления расписания в определенный филиал.
Поэтому у меня есть модель 'Branch' и модель 'Timetable'.
Модель 'Branch' находится в приложении 'branches', а модель 'Timetable' находится в приложении 'schedules'.
Я ожидаю, что когда пользователи заполнят форму для добавления расписания, они смогут выбрать филиал для добавления из поля выбора.
Вот мои коды
branches/models.py
from django.core.validators import RegexValidator
from django.db import models
from django.urls import reverse
# Create your models here.
phone_validator = RegexValidator(
regex="\d{2,4}-?\d{3,4}(-?\d{4})?",
message="It's not correct phone number format.",
)
class Branch(models.Model):
srl = models.BigAutoField(primary_key=True, verbose_name="Serial")
name = models.TextField(verbose_name="Branch name")
postcode = models.CharField(max_length=5, verbose_name="Postcode")
address1 = models.TextField(verbose_name="Road address")
address2 = models.TextField(verbose_name="Detail address", blank=True)
phone1 = models.CharField(max_length=13, validators=[phone_validator], verbose_name="Phone 1")
phone2 = models.CharField(max_length=13, validators=[phone_validator], verbose_name="Phone 2", blank=True)
is_opened = models.BooleanField(default=True, verbose_name="Is opened?")
class Meta:
verbose_name = "Branch"
verbose_name_plural = "Branches"
ordering = ["srl"]
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse("branches:detail", kwargs={"srl": self.srl})
schedules/models.py
import datetime
from django.conf import settings
from django.db import models
class Timetable(models.Model):
srl = models.BigAutoField(
primary_key=True,
verbose_name="Serial",
)
branch_srl = models.ForeignKey(
"branches.Branch",
on_delete=models.CASCADE,
verbose_name="Branch Serial",
)
period = models.DecimalField(
max_digits=2,
decimal_places=0,
verbose_name="Period",
)
period_length = models.DurationField(
default=datetime.timedelta(minutes=50),
verbose_name="Period Length",
)
is_holiday = models.BooleanField(
default=False,
verbose_name="Is holiday?",
)
start_time = models.TimeField(
default=datetime.time(10, 00),
verbose_name="Start time",
)
end_time = models.TimeField(
default=datetime.time(23, 00),
verbose_name="End time",
)
schedules/forms.py
from django import forms
from django.forms import ModelChoiceField, ModelForm
from branches.models import Branch
from schedules.models import Schedule, Timetable
class TimetableForm(ModelForm):
branch_choices = ModelChoiceField(
queryset=Branch.objects.all(),
required=True,
label="Branch",
widget=forms.Select(attrs={"class": "form-select"}),
)
class Meta:
model = Timetable
fields = (
"branch_choices",
"period",
"period_length",
"is_holiday",
"start_time",
"end_time",
)
labels = {
"period": "Period",
"period_length": "Period Length",
"is_holiday": "Is Holiday?",
"start_time": "Start Time",
"end_time": "End Time",
}
widgets = {
"period": forms.NumberInput(attrs={"class": "form-control"}),
"period_length": forms.TimeInput(
format="%H:%M:%S",
attrs={
"class": "form-control",
},
),
"is_holiday": forms.RadioSelect(
choices=[(True, "Yes"), (False, "No")],
attrs={
"class": "form-check-input",
},
),
"start_time": forms.TimeInput(
attrs={
"type": "time",
"class": "form-control",
},
),
"end_time": forms.TimeInput(
attrs={
"type": "time",
"class": "form-control",
},
),
}
Сообщение об ошибке вот такое
.
Сообщение об ошибке из режима отладки Django
Более простой способ установки связанных с кверисетом вариантов на форме модели - это переопределение метода __init__()
формы, а не создание поля формы вручную.
class TimetableForm(ModelForm):
...
def __init__(self, *args, **kwargs):
self.branches = Branch.objects.all()
super(TimetableForm, self).__init__(*args, **kwargs)
self.fields['branch_srl'].queryset = self.branches
<<<Кроме того, поскольку вы используете , многие метки и определения полей должны быть автоматическими на основе того, что вы определили в модели. Старайтесь избегать повторения этих деклараций, если вы можете этого избежать.ModelForm
Благодаря CodenameTim с Django Forum, я нашел решение
.
Поэтому я скопировал решение ниже для тех, кто испытывает ту же проблему.
Ошибка говорит, что поле branch_srl является нулевым при вставке, поэтому оно нарушает
NOT NULL CONSTRAINT
. Если вы проверите свою форму, то форма не использует это поле, а вместо него используетсяbranch_choices
. Вам нужно сопоставить выбранное значение для этого поля сbranch_srl
где-нибудь. Это может быть вTimetableForm.save()
,AddTimetableView.form_valid()
или вы можете переименовать полеbranch_choices
вbranch_srl
, чтобы оно сохранилось в базе данных.