I posted this question but I couldn't get the solutions provided to work. Instead of editing, I'm posting a new one with the modified code which uses a different approach (with two model forms)
models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
location = models.CharField(max_length=30, blank=True)
birth_date = models.DateField(null=True, blank=True)
def __str__(self):
return self.user.username
def create_profile(sender, **kwargs):
user = kwargs["instance"]
if kwargs["created"]:
user_profile= Profile(user=user)
user_profile.save()
post_save.connect(create_profile, sender=User)
forms.py
from django_superform import FormField, SuperForm
class SignUpForm(UserCreationForm):
password1 = forms.CharField(label=("Password"), widget=forms.PasswordInput)
password2 = forms.CharField(label=("Confirm password"), widget=forms.PasswordInput)
class Meta:
model = User
fields = ('username', 'first_name', 'last_name', 'email')
labels = {
'username': ('Capser name'),
}
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ('location', 'birth_date')
class SuperProfile(SuperForm):
signupform = FormField(SignUpForm)
profileform = FormField(ProfileForm)
See that I'm using the Superform from Django-superform package. The reason for that is that I'm uing a form template in my html template as explained later in the template section.
templates
html page template : registration_form.html
<form class="form-horizontal" action="" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<h1>Create a capser account</h1>
<table border="1">
{{ userform.as_table }}
{{ profileform.as_table }}
</table>
{% include 'home/form-template.html' %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-success">Create account</button>
</div>
</div>
</form>
form template : form-template.html
{% if messages %}
<ul>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% for field in form %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<span class="text-danger small">{{ field.errors }}</span>
</div>
<label class="control-label col-sm-2">{{ field.label_tag }}</label>
<div class="col-sm-10">{{ field }}</div>
<div class="col-sm-offset-2 col-sm-10">
<span class="text-danger small">{{ field.help_text }}</span>
</div>
</div>
{% endfor %}
and the views.py with the new approach (importing fields from the two model forms
views.py
class UserFormView(View):
Userform_class = SignUpForm
Profileform_class = ProfileForm
template_name = 'home/registration_form.html'
#display a blank form
def get(self, request):
userform = self.Userform_class(None)
profileform=self.Profileform_class(None)
return render (request, self.template_name, {'userform': userform, 'profileform': profileform})
#process form data
def post(self, request):
userform = self.Userform_class(request.POST)
profileform = self.Profileform_class(request.POST)
if userform.is_valid() and profileform.is_valid():
user = userform.save(commit=False)
#user.refresh_from_db() # load the profile instance created by the signal
password = userform.cleaned_data['password1']
user.set_password(password)
username = userform.cleaned_data['username']
first_name=userform.cleaned_data['first_name']
last_name=userform.cleaned_data['last_name']
email = userform.cleaned_data['email']
user.save()
new_profile = user_profile.objects.get(user = request.user)
new_profile.objects.create(
user=user,
location=profileform.cleaned_data.get('location'),
birth_date=profileform.cleaned_data.get('birth_date'))
new_profile.save()
#return user objects if credentials are correct
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return redirect('home:home')
return render (request, self.template_name, {'userform': userform, 'profileform':profileform})
Now when I submit my form, I get the following error : name 'user_profile' is not defined
I thought that the user_profil
e was the instance created at the end of my model.py
file.
So if this doesn't work like so, how do I call the instance of my Profile model in the view ?
I've tried a lot of solutions and none worked so far.
Also, I initially wanted to use my form-template in order to display my form on the html page, but now that I use two model forms userform and profileform, I wonder on how to use my form template (I tried with Superform without success).