Search code examples
pythondjangodjango-registration

How to create a profile registration form in Django?


I am trying to create a custom registration form, but I don't really know how to do it since I am trying to connect the default django registration with a new model.

here is what it looks like, it might be wrong but I am thinking to something like this.

models.py

class Profile(models.Model):
    user = models.OneToOneField(User)
    name = models.CharField(max_length=20, blank=True, null=True)
    description = models.TextField(max_length=400)

views.py

def register_user(request):
    if request.user.is_authenticated():
        return HttpResponseRedirect('/user/')
    else:
        if request.method == 'POST':
            form = MyRegistrationForm(request.POST)
            if form.is_valid():
                form.save()
                return HttpResponseRedirect('/user/')

        context = {'profil':Profile.objects.all()}
        context.update(csrf(request))
        context['form'] = MyRegistrationForm()

        return render(request, 'register.html', context)

forms.py

class MyRegistrationForm(UserCreationForm):
    email = forms.EmailField(required=True)

    class Meta:
        model = User
        fields = {'username', 'password1', 'password2', 'email'}

    def save(self, commit=True):

        my_user = super(MyRegistrationForm, self).save(commit=False)
        my_user.email = self.cleaned_data['email']

        new_profile = Profile(user=my_user, name="John", description="a person")

        if commit:
            new_profile.save()

        return new_profile

register.py

<form action="/user/register/" method="post" id="register" autocomplete="off">
{% csrf_token %}
<div class="fieldWrapper">
  {{ form.username.errors }}
  {{ form.username.label_tag }}
  {{ form.username }}
</div>
[... other fiels ...]
<input type="submit" value="Register"/>
</form>

I'm trying to connect the model with the form, so when someone register and when I type his name in the template like this : {{user.name}} It should be "John".

How can I achieve this goal?


Solution

  • Also in order to get the name in the template you have to access it like {{ user.profile.name }} since name is saved in the Profile Model

    But if you want to create a form for your Profile model you can do it like this

    class ProfileForm(forms.ModelForm):
        class Meta:
             model = Profile
             fields = ("name", "description")
    

    Also if you plan to use both the UserCreationForm and the ProfileForm both in the same HTML Form you should add a prefix to them to know which data belongs to which form, look how to do it here https://docs.djangoproject.com/en/1.9/ref/forms/api/#prefixes-for-forms

    Edit

    def register_user(request):
        #...
        if request.method == "POST":
            user_form = UserCreationForm(request.POST, prefix="user")
            profile_form = ProfileForm(request.POST, prefix="profile")
            if user_form.is_valid() and profile_form.is_valid():
                user = user_form.save(commit=False)
                user.save()
                profile = profile_form.save(commit=False)
                profile.user = user
                profile.save()
                return redirect('/')
        else:
            user_form = UserCreationForm(prefix="user")
            profile_form = ProfileForm(prefix="profile")
        context = {
            "user_form": user_form,
            "profile_form": profile_form
        }
        return render(request, 'register.html', context)
    

    Then in the template

    <form action="/user/register/" method="post" id="register" autocomplete="off">
    {% csrf_token %}
    <div class="fieldWrapper">
        {{ user_form }}
        {{ profile_form }}
    </div>
    <input type="submit" value="Register"/>