This site runs best with JavaScript enabled.

Django: Filtering a ModelForm field


How to filter a ModelForm by foreign key in Django

So something what should be so relatively easy can turn out to be quite hard when you don't know where to go for the answer. Generally the #django channel on IRC is an awesome help, but this morning I felt invisible so I can too keep digging. Finally I found my answer in code from another project.

Here's the situation. I'm creating a budget system. When you add or import transactions from your bank, you need to tell it what bank account the transactions are associated with. I have the following models: Bank, BankAccount, Transaction. Transaction has a foreign key to BankAccount.

I have a ModelForm named AddTransactionForm. The problem was that when I went to add a transaction, it would show me all the accounts of other users. I needed to somehow filter the queryset that was applied to the account foreign key. I couldn't find this anywhere in the docs, and like I mentioned, no one was even acknowledging me in IRC, which is rare. I finally found something similar I did for HouseSheet.com. Here was is my "fixed" form class:

1class AddTransactionForm(ModelForm):
2 def __init__(self, user, *args, **kwargs):
3 super(AddTransactionForm, self).__init__(*args, **kwargs)
4 self.fields['account'] = forms.ModelChoiceField(queryset=BankAccount.objects.filter(user=user))
5
6
7 class Meta:
8 model = Transaction
9 exclude = ('envelope',)

So now, when I call this, I just need to pass in the the logged in user to show only that user's accounts like so: form = ImportForm(user=request.user)

I think my biggest problem with this was I haven't yet mastered the python language so I wasn't sure how to pass in the user object I need to filter on.

Discuss on TwitterEdit post on GitHub

Share article
Dustin Davis

Dustin Davis is a software engineer, people manager, hacker, and entreprenuer. He loves to develop systems and automation. He lives with his wife and five kids in Utah.

Join the Newsletter



Dustin Davis