1

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?

orokusaki
  • 55,146
  • 59
  • 179
  • 257

2 Answers2

2

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
  • 24,375
  • 3
  • 55
  • 55
  • 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 Dec 23 '09 at 06:22
  • 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 Dec 23 '09 at 06:38
1

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
  • 55,146
  • 59
  • 179
  • 257