Я работаю над проектом, используя Python (3.7) и Django (2.2), в котором мне нужно создавать различные формы, у меня есть две формы: форма User
и форма Profile
, на на стороне шаблона я должен объединить их, поэтому я использовал MultiModelForm для этой цели, он работает для других моих моделей, но для одной CoachAccount
модели он не работает.
Вот что Я пробовал до сих пор:
С models.py
:
class CoachAccount(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE,)
dob = models.DateField(blank=False)
passport_number = models.CharField(max_length=255, blank=True)
nationality = models.CharField(max_length=255, choices=NATIONALATIES, blank=True)
fax = models.BigIntegerField(blank=True)
correspondent_address = models.CharField(max_length=255, blank=True)
apply_for = MultiSelectField(choices=APPLY_FOR_CHOICES, blank=True)
emergency_gender = models.CharField(max_length=255, choices=GENDER_CHOICES)
emergency_title = models.CharField(max_length=255, choices=TITLE)
emergency_name = models.CharField(max_length=255)
relationship = models.CharField(max_length=255)
telephone = PhoneNumberField(blank=True, null=True, max_length=13,
help_text='Phone number must be entered in the'
'format: \'+999999999\'. Up to 13 digits allowed.')
emergency_email = models.EmailField(max_length=255)
driving_license = models.CharField(max_length=50, choices=HAVE_DRIVING_LICENCE, blank=True, null=True)
driving_license_type = MultiSelectField(max_length=255, choices=DRIVING_LICENCE_CHOICES, blank=True, null=True)
have_accidents = models.BooleanField(max_length=30, blank=True,)
how_many_accidents = models.IntegerField(blank=True, null=True)
have_moving_violations = models.BooleanField(max_length=30, blank=True)
how_many_moving_violations = models.IntegerField(blank=True, null=True)
have_convicted_crime = models.BooleanField(max_length=30, blank=True)
how_many_convicted_crime = models.IntegerField(blank=True, null=True)
working_with_cycling = models.BooleanField(max_length=30)
bank_name = models.CharField(max_length=255, blank=True)
bank_code = models.CharField(max_length=255, blank=True)
branch_code = models.CharField(max_length=255, blank=True)
account_number = models.CharField(max_length=255, blank=True)
account_holder_name = models.CharField(max_length=255, blank=True)
bank_proof = models.FileField(upload_to='media/bank_proofs', blank=True)
rel_doc_contract = models.BooleanField(max_length=30, blank=True)
rel_doc_contract_date = models.DateField(blank=True, null=True)
rel_doc_contract_file = models.FileField(upload_to='media/RelDocs', blank=True, null=True)
id_proof = models.BooleanField(blank=True, null=True)
id_proof_file = models.FileField(upload_to='media/RelDocs', blank=True, null=True)
proof_qualification = models.BooleanField(blank=True)
proof_qualification_name = models.CharField(max_length=255, blank=True)
proof_qualification_date = models.DateField(blank=True, null=True)
proof_qualification_file = models.FileField(upload_to='media/RelDocs', blank=True)
first_aid = models.BooleanField(blank=True)
first_aid_date = models.DateField(blank=True, null=True)
first_aid_file = models.FileField(upload_to='media/RelDocs', blank=True)
drv_licence_copy = models.BooleanField(blank=True)
drv_licence_copy_date = models.DateField(blank=True, null=True)
drv_licence_copy_file = models.FileField(upload_to='media/RelDocs', blank=True)
sex_convic_record = models.BooleanField(blank=True)
sex_convic_record_date = models.DateField(blank=True, null=True)
sex_convic_record_file = models.FileField(upload_to='media/RelDocs', blank=True)
auth_ref_check = models.BooleanField(blank=True)
auth_ref_check_file = models.FileField(upload_to='media/RelDocs', blank=True)
annual_health_consent = models.BooleanField(blank=True)
annual_health_consent_date = models.DateField(blank=True, null=True)
annual_health_consent_file = models.FileField(upload_to='media/RelDocs', blank=True)
consent_declaration = models.CharField(choices=CONSENT_CHOICES, max_length=1000, blank=True)
offer_type = MultiSelectField(choices=OFFER_CHOICES, blank=True)
position_reffered = models.CharField(max_length=255, blank=True)
department = models.CharField(max_length=255, blank=True)
internship = models.CharField(choices=CONSENT_CHOICES, max_length=100, blank=True)
system_access_permission = MultiSelectField(choices=OFFER_CHOICES, blank=True)
Вот мой forms.py
:
class CoachForm(forms.ModelForm):
class Meta:
model = CoachAccount
fields = (
'dob', 'passport_number', 'nationality', 'fax', 'correspondent_address', 'apply_for', 'emergency_gender',
'emergency_title',
'emergency_name', 'relationship', 'telephone', 'emergency_email', 'driving_license', 'driving_license_type',
'have_accidents', 'how_many_accidents', 'have_moving_violations', 'how_many_moving_violations',
'have_convicted_crime', 'how_many_convicted_crime', 'working_with_cycling', 'bank_name', 'bank_code',
'branch_code',
'account_number', 'account_holder_name', 'bank_proof', 'rel_doc_contract', 'rel_doc_contract_date',
'rel_doc_contract_file', 'id_proof', 'id_proof_file', 'proof_qualification', 'proof_qualification_name',
'proof_qualification_date', 'proof_qualification_file', 'first_aid', 'first_aid_date', 'first_aid_file',
'drv_licence_copy', 'drv_licence_copy_date', 'drv_licence_copy_file', 'sex_convic_record',
'sex_convic_record_date',
'sex_convic_record_file', 'auth_ref_check', 'auth_ref_check_file', 'annual_health_consent',
'consent_declaration',
'annual_health_consent_date',
'annual_health_consent_file', 'offer_type', 'position_reffered', 'department',
'internship', 'system_access_permission')
class UserCoachAccount(MultiModelForm):
form_classes = {
'user': UserForm,
'profile': CoachForm
}
С html template
:
<form action="{% url 'dashboard:new-coach-account' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
{% if messages %}
{% for message in messages %}
<div class="alert alert-{{ message.tags }} alert-dismissible fade show mt-3" role="alert">
{{ message }}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
{% endfor %}
{% endif %}
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endif %}
{{ form|crispy }}
</form>
С urls.py
:
path('user/add/coach_staff/', views.CreateCoachAccount.as_view(), name='new-coach-account'),
С views.py
:
class CreateCoachAccount(LoginRequiredMixin, generic.CreateView):
def get(self, request, *args, **kwargs):
form = UserCoachAccount()
return render(request, 'dashboard/add_coach_account.html',
{'form': form})
def post(self, request, *args, **kwargs):
post_data = request.POST.copy()
post_data.update({'user-user_type': 'CA'})
form = UserCoachAccount(request.POST, request.FILES)
if form.is_valid():
user_form = form['user']
profile_form = form['profile']
unique_id = generate_cid()
c_id = unique_id
print('save user')
user = user_form.save(commit=False)
user.email_status = False
profile = profile_form.save(commit=False)
user_form.save()
profile.user = user
profile.customer_id = c_id
print(profile)
profile.save()
messages.success(request, 'User with id {} created successfully.'.format(unique_id))
return HttpResponseRedirect(reverse_lazy('dashboard:new-coach-account'))
else:
messages.error(request, messages.ERROR, form.errors)
print(form.errors)
return HttpResponseRedirect(reverse_lazy('dashboard:new-coach-account'))
Первая часть форма, которая является User
формой, сохраняется в БД (имеется в виду пользователь создан), но вторая часть, которая profile
не сохраняется в базе данных. Это работает для других моделей, но не знаю, почему не работает здесь, я попробовал почти все, что приходит мне в голову, и сделал поиск в Google и здесь, в Stackoverflow, но не смог найти никакого решения для этого. что тут может быть не так?