views:

123

answers:

2

My app has clients that each have a single billing profile.

I'm envisioning my app having a "Client" model with an attribute called "billing_profile" which would reference another model called "BillingProfile". Rather than define "BillingProfile" with a foreign key back to "Client" (ie, "client = models.ForeignKey(Client)"), I was thinking that since there will only be one billing profile for each client that I could simply use a one-to-one field instead. Does this seem logical to do, or does it seem backwards (Then I would have to create a BillingProfile before ever establishing a Client). Is there a good way to do this versus my paradigm of understanding it?

+2  A: 

That's the way to do it, if you are certain its a one to one relationship. for example, could there be a client with 2 billing profiles: one for personal use, and for his business, &c...

It is not backwards, because using a one to one, or using a foreign key doesn't affect the order of creation (in both you can create the profile first, or create the client first, and then link them).

Ofri Raviv
Thanks Ofri. How could I create a Client without it's billing_profile attribute set (ie, without it's BillingProfile created) unless either A) I used blank=True (which I want all Clients to have a BillingProfile) or B) I use save(commit=False) on my new Client, then create the BillingProfile and add it to the Client and then use save() again on the Client. Am I thinking of this all wrong?
orokusaki
These are 2 ways to do it. some more ideas can be found here: http://stackoverflow.com/questions/1652550/can-django-automatically-create-a-related-one-to-one-model
Ofri Raviv
A: 

I figured it out.

A OneToOneField() can be looked up both ways via the simple attribute method.

Example:

Models:

class Client(models.Model):
    ... stuff ...


class BillingProfile(models.Model):
     client = models.OneToOneField('Client')
    ... stuff ...

Now I can do either of these:

spam_client.billingprofile  # returns related BillingProfile Instance

or

spam_billingprofile.client  # returns related Client instance

This means I don't have to instantiate the BillingProfile until I'm ready, but I still have the benefits that I would have if the Client had a billingprofile attribute instead of the other way around.

In other words: I was thinking of it all backwards before, but not too backwards.

orokusaki