When attempting to register a new user through the registration form, the phone number (phone_number) and library ID (library_id) fields are not being saved to the database. Despite these fields being included in the registration form and rendered correctly, the submitted values are not written the database.
def user_register(request):
userIsAuthenticated = False
if request.user.is_authenticated:
username1 = request.user.username
userIsAuthenticated = True
else:
username1 = "N/A"
userIsAuthenticated = False
if request.method == 'GET':
form = RegisterForm()
return render(request, "register.html", {"form":form, "username": username1, "userIsAuthenticated": userIsAuthenticated})
if request.method == 'POST':
form = RegisterForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.save()
login(request, user)
return render(request, "register-success.html")
else:
return render(request, 'register.html', {"form":form, "username": username1, "userIsAuthenticated": userIsAuthenticated})
class RegisterForm(UserCreationForm):
first_name = forms.CharField(max_length=100)
last_name = forms.CharField(max_length=100)
library_id = forms.CharField(max_length=100)
phone_number = forms.CharField(max_length=100)
class Meta:
model = User
fields = ['first_name', 'last_name', 'username', 'email', 'password1', 'password2']
def save(self, commit=True):
user = super().save(commit=False)
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.email = self.cleaned_data['email']
if commit:
Profile.objects.create(
user=user,
phone_number=self.cleaned_data['phone_number'],
library_id=self.cleaned_data['library_id']
)
user.save()
return user
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
phone_number = models.CharField(max_length=100)
library_id = models.CharField(max_length=100)
def __str__(self):
return self.user.username
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
More details (registration process, the problem in better detail):
id | username | first_name | last_name | |
---|---|---|---|---|
27 | dolor | Lorem | ipsum | sit@amet.consectetur |
The rest of the details are saved in the Profile model. Let's look at it!
id | user_id | phone_number | library_id |
---|---|---|---|
12 | 27 | "" | "" |
Here, the data from the form we filled out are not saved.
Additionaly, I am able to fill out those fields (phone_number, library_id) using the admin panel, so the problem is most likely in the user_register function.
It's because the logic where you save that information on the Profile
model is contingent on commit=True
in your form's .save()
method.
But you never call RegisterForm.save(commit=True)
, you only ever call it with commit=False
. That means the Profile
-logic is never executed. The reason you get a Profile
object in the database at all, is due to the create_user_profile
-signal.
def save(self, commit=True):
user = super().save(commit=False)
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.email = self.cleaned_data['email']
if commit: # <---- NB! Conditional execution only when commit=True
Profile.objects.create(
user=user,
phone_number=self.cleaned_data['phone_number'],
library_id=self.cleaned_data['library_id']
)
user.save()
return user
def user_register(request):
[...]
if request.method == 'POST':
form = RegisterForm(request.POST)
if form.is_valid():
user = form.save(commit=False) # <-- NB! commit=False
There's a lot of ways you can do this, but you're gonna have to decide on how to handle the save-logic between your form and your model(s).