anttikoo
anttikoo

Reputation: 815

How to save form data to different models with one-to-one relationship in Django

This is actually a follow-up to a previous question.

A user's profile data is spread over several different models, like so:

# Simplified versions, actual classes contain many more fields.

class Profile(models.Model):  # returned by Django's User.get_profile()
    user = models.OneToOneField(User)  

    home_address = models.OneToOneField(Address)
    work_address = models.OneToOneField(Address)

    language = models.CharField(max_length=20)

class Address(models.Model):
    street = models.CharField(max_length=100)
    city = models.CharField(max_length=100)

... and Django's User, of course.

I want the user to enter all of his profile data in one view, in particular these pieces of information:

So, what would be the simplest/Django way to

  1. construct such a form?
  2. output the form in the template?
  3. handle the incoming form data, split it to different models and create the necessary objects (i.e. a User, a Profile and 2 Address objects)?

Upvotes: 2

Views: 3174

Answers (2)

Mp0int
Mp0int

Reputation: 18747

Most practical way is, i guess, using modelForm and formsets...

You can use model form to create forms from a model. Docs here.... You can use inline formset to create forms and save data easily... Doc here...

But, of course, related models must have foreignkey to either user or Profile. Your model structure may not be suitable, because as far as i know, inlined model must have a foreignkey to the other, so at this point, your foreignkey to Profile needed to be in Address model... But as i said, i am not sure.you may give it a try...

Since you have proper foreignKey relations, you can use inline formsets with modelform to create a form from many models...

EDIT:

As far as i understand, you can either use modelforms (without formsets) and easily cerate your form in the template. But in your view function that will process the posted data, you have to set foreign one to one connections manually. Like:

home = Address.objects.create(...)
work = Address.objects.create(...)
Profile.objects.create(home_address=home, work_address=work,...)

Or you can alter your models:

class Profile(models.Model):  # returned by Django's User.get_profile()
    user = models.OneToOneField(User)  
    language = models.CharField(max_length=20)

class Address(models.Model):
    profile = models.ForeignKey(Profile)
    street = models.CharField(max_length=100)
    city = models.CharField(max_length=100)

Upvotes: 0

Daniel Roseman
Daniel Roseman

Reputation: 600059

I think you're at the point where modelforms and formsets will require more work to customise than you will save by using them. So, I would use a standard (non-model) form, define the field types manually, and save them all to the relevant models explicitly - either in the view, or by defining your own save() method on the form and calling that.

Upvotes: 1

Related Questions