#Trying to set up profile registration - custom fields are not being stored in DB

25 messages ยท Page 1 of 1 (latest)

modest dagger
#

I am setting up a registration system that creates a new entry in my auth_user table. I'm trying to add some custom fields to the registration for firstName, lastName. that are meant to be stored in another related table littleTalkApp_profile

The registration form works and a new entry into littleTalkApp_profile is created, but the firstName, lastName fields are [null]

On the web app, I've used dev tools to inspect the registration post request and the payload seems to get everything:

status code: 302 found

username: test
email: test@test.com
firstName: test
lastName: test2
password1: 1234
password2: 1234
#

So I guess I've coded something wronng, but can't see any issues - I'll share my code below:

hollow crane
#

We are probably going to need the code of the view you are POSTing this data to

modest dagger
#

Hey Kag_ee ๐Ÿ™‚ coming right up

#

view:


def register(request):
    if request.method == 'POST':
        form = UserRegistrationForm(request.POST)
        if form.is_valid():
            # Create and save the user
            username = form.cleaned_data.get('username')
            email = form.cleaned_data.get('email')
            password = form.cleaned_data.get('password1')
            user = User.objects.create_user(username=username, email=email, password=password)

            # Extract additional fields from the form
            firstName = form.cleaned_data.get('firstName')
            lastName = form.cleaned_data.get('lastName')

            # Save the profile data
            profile = Profile.objects.get(user=user)  # Ensure we get the associated profile
            profile.firstName = firstName
            profile.lastName = lastName
            profile.save()  # Save the updated profile

            # Log the user in and redirect to home
            login(request, user)
            return redirect('home')
    else:
        form = UserRegistrationForm()

    return render(request, 'registration/register.html', {'form': form})
#

Form:

class UserRegistrationForm(forms.ModelForm):
    firstName = forms.CharField(max_length=100, label="First Name")  
    lastName = forms.CharField(max_length=100, label="Last Name")
    password1 = forms.CharField(widget=forms.PasswordInput, label="Password")
    password2 = forms.CharField(widget=forms.PasswordInput, label="Confirm Password")

    class Meta:
        model = User
        fields = ['username', 'email']  

    def clean_password2(self):
        password1 = self.cleaned_data.get('password1')
        password2 = self.cleaned_data.get('password2')

        if password1 and password2 and password1 != password2:
            raise forms.ValidationError("Passwords do not match")
        return password2
#

models.py:

from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver


class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
    firstName = models.CharField(max_length=100, blank=True, null=True)
    lastName = models.CharField(max_length=100, blank=True, null=True)

    def __str__(self):
        return f"{self.user.username}'s Profile"
    

@receiver(post_save, sender=User)
def create_or_update_user_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)
    else:
        instance.profile.save()
hollow crane
#

I see signals. Without even having read the code i am going to say it is probably not smart to use ๐Ÿ˜›

modest dagger
#

okay, yeah I heard about using get_or_create instead as this doesn't rely so much on signals

#

but haven't got round to it yet

hollow crane
#

Not sure if that is the solution, i just basicly say "Signals are always the wrong solution."

modest dagger
#

Noted, wait - do you think that might be why I'm having this issue?

hollow crane
#

Is a unstable variable you should get rid of that might be relevant ๐Ÿ˜…

#

You are creating your users in the view anyway, why not just create the profile instance there as well.

#

But the signal is also the only thing i am uncertain of, everything else looks correct

#

Btw, not sure how experienced you are with Python but snake_case is generally preferred for variable names, attributes, etc. (so first_name, not firstName). CameCase is generally for class names.

modest dagger
#

Okay good tips - but yeah I thought the code seems all okay too, argh!

#

Well I guess I'll update such that it isn't relying on signals and we can hope

hollow crane
#

I would generally recommend you check out a linter/formater. Ruff is very good and also has a vscode extention and will link you to explanations when it tells you something is "wrong", so you can learn why.

modest dagger
#

Managed to fix this - it looks like it was the signals after all - I removed the @receiver func from models.py and updated my register view to :

def register(request):
    if request.method == 'POST':
        form = UserRegistrationForm(request.POST)
        if form.is_valid():
            username = form.cleaned_data.get('username')
            email = form.cleaned_data.get('email')
            password = form.cleaned_data.get('password1')
            user = User.objects.create_user(username=username, email=email, password=password)

            first_name = form.cleaned_data.get('first_name')
            last_name = form.cleaned_data.get('last_name')

            Profile.objects.create(user=user, first_name=first_name, last_name=last_name)

            login(request, user)
            return redirect('home')
    else:
        form = UserRegistrationForm()

    return render(request, 'registration/register.html', {'form': form})
#

now it works ๐Ÿ˜„

#

also I installed Ruff

hollow crane
#

Told you ๐Ÿ˜‚