Search code examples
djangodjango-modelsdjango-formsdjango-viewsdjango-users

How to create view that saves User and UserProfile objects in Django


I have two models in Django: User (pre-defined by Django) and UserProfile. The two are connected via a Foreign Key.

models.py:

class UserProfile(models.Model):
  user = models.ForeignKey(User, unique=True, related_name="connect")
  location = models.CharField(max_length=20, blank=True, null=True)

I'm using UserCreationForm (pre-defined by Django) for the User Model, and created another form for UserProfile in forms.py

#UserCreationForm for User Model

class UserProfileForm(ModelForm):
  class Meta:
    model = UserProfile
    exclude = ("user", )

I load both these forms in a template, registration.html, so the website customer can enter data about fields contained in both models (ex: "first_name", "last_name" in User model, "location" in UserProfile model).

For the life of me, I can't figure out how to create a view for this registration form. What I've tried so far will create the User object, but it will not associate other information such as location in the corresponding UserProfile object. Can anyone help me out? This is what I currently have:

def register(request):
  if request.method == 'POST':
    form1 = UserCreationForm(request.POST)
    form2 = UserProfileForm(request.POST)
    if form1.is_valid():
      #create initial entry for User object
      username = form1.cleaned_data["username"]
      password = form1.cleaned_data["password"]
      new_user = User.objects.create_user(username, password)

      # What to do here to save "location" field in a UserProfile 
      # object that corresponds with the new_user User object that 
      # we just created in the previous lines

  else:
    form1 = UserCreationForm()
    form2 = UserProfileForm()
  c = {
    'form1':UserCreationForm,
    'form2':form2,
  }
  c.update(csrf(request))
  return render_to_response("registration/register.html", c)

Solution

  • Almost there :)

    def register(request):
        if request.method == 'POST':
            form1 = UserCreationForm(request.POST)
            form2 = UserProfileForm(request.POST)
            if form1.is_valid() and form2.is_valid():
                user = form1.save()  # save user to db
                userprofile = form2.save(commit=False)  # create profile but don't save to db
                userprofile.user = user
                userprofile.location = get_the_location_somehow()
                userprofile.save()  # save profile to db
    
        else:
            form1 = UserCreationForm()
             form2 = UserProfileForm()
        c = {
          'form1':form1,
          'form2':form2,
        }
        c.update(csrf(request))
        return render_to_response("registration/register.html", c)
    

    To clarify a bit, form.save() creates an instance of the Model and saves it to db. form.save(commit=False) Just creates an instance, but is does not save anything to db.