Foreign Key value not populated

I’m at a loss as to why there is never a foreign key value assigned to the rrif_income field in the RrifAccount model

For this scenario, I have an Account model that can include 3 types of accounts: generic, Personal and rrif. The rrif model, if present, will always include a relationship to the RrifIncome model via foreign key. All data is correctly populated in the database for this scenario, except the rrif_income foreign key value is always null.

Can anyone shred some light as to why this could be happening?

Thanks!

**accounts.model.py**

from django.db import models
from plans.incomes.models import RrifIncome

class Accounts(models.Model):

    # Fields
    name = models.CharField(max_length=255)
    created = models.DateTimeField(auto_now_add=True, editable=False)
    last_updated = models.DateTimeField(auto_now=True, editable=False)

    # Relationship Fields
    generic_account = models.ForeignKey(
        GenericAccount,
        on_delete=models.CASCADE, related_name="accountss", 
    )
    personal_account = models.ForeignKey(
        PersonalAccount,
        on_delete=models.CASCADE, related_name="accountss", 
    )
    rrif_account = models.ForeignKey(
        RrifAccount,
        on_delete=models.CASCADE, related_name="accountss", 
    )

class GenericAccount(models.Model):

    # Fields
    name = models.CharField(max_length=255)
    created = models.DateTimeField(auto_now_add=True, editable=False)
    last_updated = models.DateTimeField(auto_now=True, editable=False)

class PersonalAccount(models.Model):

    # Fields
    name = models.CharField(max_length=255)
    created = models.DateTimeField(auto_now_add=True, editable=False)
    last_updated = models.DateTimeField(auto_now=True, editable=False)

class RrifAccount(models.Model):

    # Fields
    name = models.CharField(max_length=255)
    created = models.DateTimeField(auto_now_add=True, editable=False)
    last_updated = models.DateTimeField(auto_now=True, editable=False)

    # Relationship Fields
    rrif_income = models..ForeignKey(
        RrifIncome,
        on_delete=models.CASCADE, related_name="rrifaccounts", 
    )

**income.model.py**

from django.db import models

class RrifIncome(models.Model):

    # Fields
    name = models.CharField(max_length=255)
    created = models.DateTimeField(auto_now_add=True, editable=False)
    last_updated = models.DateTimeField(auto_now=True, editable=False)

Aside from the syntactical error of having two periods in models..ForeignKey, we’d need to see how you’re creating these instances and sample data showing the problem for us to try and diagnose this.

Also, your comments at the top of the files aren’t consistent.
You show:

But then write:

which doesn’t match.

(I know this is just a typo in what you entered here, so I’m discounting this as any possible cause.)

Please, in the future, copy / paste the actual code, do not try to retype it. It’s too easy to introduce errors that way.

Hi Ken,

Regarding the income model you commented on, I was trying to highlight they are 2 different model.py files in 2 separate folders.

The rrif_income foreign field is not populated in RrifAccount. To clarify, the RrifAccount model is in the accounts folder and the RrifIncome model is in the incomes folder. This is why I am importing RrifIncome from plans.incomes.model in the accounts folder. I know this is possible, but am I correctly referencing the foreign key in the RrifAccount model?

Everything is correctly populated in the database. The foreign key values in Account correctly reference the correct relationship between the other 3 different account, but the issue is with the rrif_income foreign key value.

rrif_income = models.ForeignKey(RrifIncome, on_delete=models.CASCADE, null=True, related_name="rrifaccounts")

The RrifAccount model

from django.db import models
from plans.incomes.models import RrifIncome

class RrifAccount(models.Model):

    objects = None

    class Meta:
        db_table = "accounts_rrif"

    IS_CONVERTED = [
        ("Y", "Yes"),
        ("N", "No"),
    ]

    CURRENCY = [
        ("CAD", "CAD (Canadian)"),
        ("USD", "USD (American)"),
    ]

    BENEFICIARY = [
        ("S", "Spouse"),
        ("E", "Estate"),
    ]

    id = models.AutoField(primary_key=True)
    username = models.CharField(max_length=50)
    owner = models.CharField(max_length=50)
    type = models.CharField(max_length=5, default="RRIF")
    desc = models.CharField(max_length=50)
    is_converted = models.CharField(max_length=1, choices=IS_CONVERTED, default="N")
    converted_year = models.PositiveIntegerField(validators=[MinValueValidator(1950), MaxValueValidator(2050)], blank=True, null=True, default=current_year)
    balance_last_year = models.DecimalField(decimal_places=2, max_digits=10, blank=True, null=True, validators=[MinValueValidator(Decimal('0.00'))])
    balance = models.DecimalField(decimal_places=2, max_digits=10, blank=True, null=True, validators=[MinValueValidator(Decimal('0.00'))])
    currency = models.CharField(max_length=3, choices=CURRENCY)
    growth = models.DecimalField(decimal_places=2, max_digits=5, validators=[MinValueValidator(Decimal('0.00'))], default=Decimal('2.00'))
    beneficiary = models.CharField(max_length=1, choices=BENEFICIARY)
    use_spouse_age = models.BooleanField(default=True, null=True)
    rrif_income = models.ForeignKey(RrifIncome, on_delete=models.CASCADE, null=True, related_name="rrifaccounts")
    active = models.BooleanField(default=True)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

And here is the RrifAccountForm

class RrifAccountForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.helper = FormHelper(self)
        self.helper.layout = Layout(Field('owner',
                                          'desc',
                                          'is_converted',
                                          'converted_year',
                                          PrependedText('balance_last_year', '$', placeholder='0.00'),
                                          PrependedText('balance', '$', placeholder='0.00'),
                                          'currency',
                                          PrependedText('growth', '%', placeholder=2.0),
                                          'beneficiary',
                                          'use_spouse_age'))

        self.helper.add_input(Submit('submit', 'Submit', css_class='btn-primary'))

    class Meta:
        model = RrifAccount

        fields = ['owner', 'desc', 'is_converted', 'converted_year', 'balance_last_year', 'balance',
                  'currency', 'use_spouse_age', 'growth', 'beneficiary']

        widgets = {'desc': forms.TextInput(attrs={'style': 'max-width: 30em'}),
                   'is_converted': forms.Select(attrs={'style': 'max-width: 12em'}),
                   'converted_year': forms.NumberInput(attrs={'style': 'max-width: 12em'}),
                   'balance_last_year': forms.NumberInput(attrs={'style': 'max-width: 9.6em', 'min': 0}),
                   'balance': forms.NumberInput(attrs={'style': 'max-width: 9.6em', 'min': 0}),
                   'currency': forms.Select(attrs={'style': 'max-width: 12em'}),
                   'use_spouse_age': forms.CheckboxInput(attrs={'style': 'max-width: 12em'}),
                   'growth': forms.NumberInput(attrs={'style': 'max-width: 9.6em'}),
                   'beneficiary': forms.Select(attrs={'style': 'max-width: 12em'})
                   }

        labels = {'owner': 'Owner',
                  'desc': 'Description',
                  'is_converted': 'Has the RRIF already been converted?',
                  'converted_year': 'Converted year?',
                  'balance_last_year': 'Balance last year' + ' (' + str(current_year-1) + '-12-31)',
                  'balance': 'Account Balance' + ' (' + str(current_date) + ')',
                  'currency': 'Currency',
                  'use_spouse_age': 'Elect to use payment based on your spouses age?',
                  'growth': 'Growth Rate',
                  'beneficiary': 'Beneficiary'}

Here’s the views.py routine when account is a rrif:

def accountCreate(request, type):
    if request.method == "POST":
        if type == "RRIF":            
	    # populate rrif income to database
            form = RrifAccountForm(request.POST)
            if form.is_valid():
                rrif_form = RrifAccountForm()
                rrif = rrif_form.save(commit=False)
                rrifIncome = RrifIncome()
		
		... rrifIncome data processing 

                # save rrifIncome to database
                rrifIncome.save()

                # populate rrif fields in database

		... rrif data processing

                # save rrif to database
                rrif.rrifIncome = rrifIncome
                rrif.save()

                # populate account fields in database
                account = Accounts()

		... account data processing

                # save account to database
                account.rrif = rrif
                account.save()

You have:

But you have:

Notice the difference?

Jees, I see the difference. Missed the underscore.

It’s always nice having another set of eyes.

Thanks again!

Ken, made the change and all’s good. Thanks again for all you help on this.

Cheers