Ryan Tankersley
Ryan Tankersley

Reputation: 193

Django Foreign Key to Many to Many Table

I need help in setting up my models correctly. Say I have three models:

Account and Owners are many to many, so:

class Account(models.Model):
    number = models.CharField(max_length=10)

class Owner(models.Model):
    account = models.ManyToManyField(Account)
    fullName = models.TextField()

Then, an "AccountOwner" can make many transactions. So, if my wife and I have the same account, I can make a many transactions for t, and she can.

My first attempt at a transaction model:

class Transaction(models.Model):
    #Does not work - Could pick account owner is not on
    account = models.ForeignKey(Account)
    owner = models.ForeignKey(Owner)
    title = models.CharField('title', max_length=50)

Two foreign keys do not work. I need one foreign key on the account_owner table. Can I do this without creating an actual account_owner model?

Thank you for your time

Upvotes: 8

Views: 15030

Answers (2)

Burhan Khalid
Burhan Khalid

Reputation: 174624

I think you might be going about this the wrong way.

The transactions are tracked at the account level, so you should not have to worry about the "AccountOwner" in the transaction table; the "AccountOwner" part is just who is authorized to use that account, and that information is used elsewhere in your application.

I would suggest you do it like this:

  1. Transactions are created at the "shopping cart/basket" level, and are tied to one (or many, it depends if you want to allow partial payments) accounts.

  2. At the "shopping cart/basket" level, you can track the person logged in; and then at the checkout page show them a filtered list of accounts that they own; with a query like Owner.objects.filter(fullName='John Smith').account_set.all(); here you can track who placed the request for the transaction.

  3. In the transaction table, store the following information:

    1. Reference to the shopping cart item (from where, you can find the owner)
    2. Account used to execute the transaction.
    3. The total amount of the transaction.
    4. The total amount of the shopping cart/basket.
    5. Status of the transaction.

This way the transaction table holds information about things related to a transaction and isn't holding your "ownership" information. Tomorrow if you decide to change owners, you only have to do it in the one place that makes sense (in the Owner model), and not the transactions model.

Upvotes: 0

catavaran
catavaran

Reputation: 45575

In fact you had already created account_owner model. It is invisible in code but it is exists. You can make it visible and use through argument in M2M field:

class Owner(models.Model):
    accounts = models.ManyToManyField(Account, through='OwnerAccount')
    fullName = models.TextField()

class OwnerAccount(models.Model):
    owner = models.ForeignKey(Owner)
    account = models.ForeignKey(Account)

class Transaction(models.Model):
    owner_account = models.ForeignKey(OwnerAccount)
    title = models.CharField('title', max_length=50)

You can still access to your Owner.accounts many-2-many field as usual. So then you will call owner.acounts.add(some_account) the corresponding OwnerAccount instance will be created automatically.

Upvotes: 12

Related Questions