I am trying to create an 'Expense Tracker'. I have query regarding create view and Models with 3 hierarchical levels. For eg:-
class ExpenseYear(models.Model):
year = models.PositiveIntegerField()
class ExpenseMonth(models.Model):
month = models.CharField(max_length = 14,blank = False)
month_year = models.ForeignKey(ExpenseYear,related_name = 'month',on_delete=models.CASCADE)
class Expenses(models.Model):
expense = models.PositiveIntegerField()
expense_month = models.ForeignKey(ExpenseMonth,related_name = 'expense', on_delete=models.CASCADE)
Now, while creating CreateView for 'Expenses' model, i am facing an issue. I want to display only the months in that particular year (in 'expense_month' foreignkey), but all months of all the years are being displayed in the 'expense_month' foreignkey.
This is what i am getting - CreateView
I searched stackoverflow about limiting foreignkey choices and ended up finally with another code, but now no months are displayed in the foreign key
Forms.py
#forms.py
class ExpensesForm(forms.ModelForm):
class Meta():
model = Expenses
fields = ('expenses','expense_month')
def __init__(self, *args, **kwargs):
month_year_id = kwargs.pop('month_year_id')
super(ExpensesForm, self).__init__(*args, **kwargs)
self.fields['expense_month'].queryset = ExpenseMonth.objects.filter(month_year_id=month_year_id)
Views.py
#views.py
class ExpensesCreateView(CreateView):
model = models.Expenses
form_class = ExpensesForm
def get_form_kwargs(self):
kwargs = super(ExpensesCreateView, self).get_form_kwargs()
kwargs.update({'month_year_id': self.kwargs.get('month_year_id')})
return kwargs
However, as i said no months are displayed if i write this code.
This is what i am getting if i write the above code - CreateView
How to limit foreignkey choices? i checked Django Documentation, but i could find any particular answer for this. Can please Help me out. I have searched many questions related to this in stackoverflow and other websites. Can you please answer this question in this context itself (pls don't reply with a genenral code as, i am new to django and find it difficult to understand general answers)
Thanks in Advance !
Urls.py
#urls.py
urlpatterns = [
path('year/<int:pk>/<int:pk2>/create_expense/',views.ExpensesCreateView.as_view(),name ='create_expense'),
]
CodePudding user response:
The issue is with the get_form_kwargs
in your view:
def get_form_kwargs(self):
kwargs = super(ExpensesCreateView, self).get_form_kwargs()
kwargs.update({'month_year_id': self.kwargs.get('month_year_id')})
return kwargs
If you print(self.kwargs.get('month_year_id'))
it will probably be None
.
self.kwargs
are the URL keyword arguments you provide to the view, in your case your url is providing two arguments pk
and pk2
here:
path('year/<int:pk>/<int:pk2>/create_expense/',views.ExpensesCreateView.as_view(),name ='create_expense'),
So you have two choices, either rename the argument in the path so it is <int:month_year_id>
(I'm not sure whether you should rename pk or pk2 just from your code snippets).
or
In get_form_kwargs
get either pk
or pk2
from self.kwargs
instead of month_year_id
, for example:
kwargs.update({'month_year_id': self.kwargs.get('pk2')})