Django CreateView не создает нового пользователя из 3 связанных моделей через ModelForm
Я создал модели в проекте Django, одна из которых - расширенная модель User. Изначально я создавал пользователя с помощью двух форм, UserCreationForm и EmployeeForm, основанных на ModelForm, а затем использовал представление на основе функции для проверки данных и их сохранения. Все работало нормально, пока я не попытался ввести третью форму и не захотел использовать CreateView.
Здесь представлены модели:
class Employee(models.Model):
SENIOR = 'Sr'
JUNIOR = 'Jr'
FIRST = 'I'
SECOND = 'II'
THIRD = 'III'
GENERATIONAL_SUFFIX = [
(SENIOR, 'Senior'),
(JUNIOR, 'Junior'),
(FIRST, 'First'),
(SECOND, 'Second'),
(THIRD, 'Third'),
]
MALE = 'male'
FEMALE = 'female'
OTHER = 'other'
SEX = [
(MALE, 'Male'),
(FEMALE, 'Female'),
(OTHER, 'Other'),
]
user = models.OneToOneField(User, on_delete=models.CASCADE)
phone_regex = RegexValidator(regex=r'^\d{11}$', message="Phone number must be entered in the format: '09151234567'.")
phone_number = models.CharField(validators=[phone_regex], max_length=11, blank=True)
middle_name = models.CharField(max_length=20, blank=True)
sex = models.CharField(max_length=6, choices=SEX, blank=True)
suffix = models.CharField(max_length=3, choices=GENERATIONAL_SUFFIX, blank=True)
birthday = models.DateField(null=True, blank=True)
hire_date = models.DateField(null=True, blank=True)
image = models.ImageField(blank=True, default='blank_profile_picture.jpg')
slug = models.SlugField(max_length=60, blank=True, null=True)
updated = models.DateTimeField(auto_now=True)
@property
def get_full_name(self):
first_name = self.user.first_name
middle_name = self.middle_name
last_name = self.user.last_name
if middle_name is None:
full_name = f'{first_name}{" "}{last_name}'
return full_name
else:
full_name = f'{first_name}{" "}{middle_name}{" "}{last_name}'
return full_name
def save(self, *args, **kwargs):
self.slug = slugify(self.get_full_name)
super().save(*args, **kwargs)
def __str__(self):
return self.get_full_name
class EmployeePosition(models.Model):
employee = models.ForeignKey(Employee, on_delete=models.CASCADE)
position = models.ForeignKey(Position, on_delete=models.CASCADE)
position_change_reason = models.ForeignKey(PositionChangeReason, on_delete=models.CASCADE, default='Hired As')
effective_date = models.DateField()
def __str__(self):
return str(self.position)
Здесь представлены 3 формы:
В третьей форме я попытался установить значения по умолчанию для двух полей на случай, если пользователь не введет их.
Вот как выглядит вид:
class RegisterEmployeeView(LoginRequiredMixin, CreateView):
model = User
form_class = EmployeeRegistrationForm
profile_form_class = EmployeeForm
position_form_class = EmployeePositionForm
template_name = 'accounts/register.html'
success_url = '/'
def get(self, request, *args, **kwargs):
form = self.form_class(**self.get_form_kwargs())
profile_form = self.profile_form_class(prefix='profile_form')
position_form = self.position_form_class(prefix='position_form')
return render(request, self.template_name,
{'form': form, 'profile_form': profile_form, 'position_form': position_form})
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
profile_form = self.profile_form_class(request.POST)
position_form = self.position_form_class(request.POST)
if form.is_valid() and profile_form.is_valid() and position_form.is_valid():
user = form.save()
profile = profile_form.save(commit=False)
position_profile = position_form.save(commit=False)
profile.user = user
position_profile.employee = profile.employee
profile.save()
position_profile.save()
messages.success(self.request, f'{User.first_name}{" "}{User.last_name}{" was registered successfully."}')
return HttpResponseRedirect(self.get_success_url())
else:
context = {'form': form, 'profile_form': profile_form, 'position_form': position_form}
return render(request, self.template_name, context)
I've read dozens of articles here and other sites that have similar issues, but couldn't work it out. It seems similar to what Risadinha said here: "it's not saving and not redirecting" := that is what happens when there is a validation error. But I can't wrap my head around this as I'm still learning Django.