Форма Создать представление и 3 иерархические модели - Ограничение выбора для ForeignKey
Я пытаюсь создать 'Expense Tracker'. У меня есть запрос относительно создания представления и модели с 3 иерархическими уровнями. Например:-
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)
Теперь, при создании CreateView для модели 'Expenses', я столкнулся с проблемой. Я хочу отобразить только месяцы этого года (во внешнем ключе 'expense_month'), но все месяцы всех лет отображаются во внешнем ключе 'expense_month'.
Вот что я получаю - CreateView
Я искал в stackoverflow об ограничении выбора внешнего ключа и в итоге пришел к другому коду, но теперь во внешнем ключе не отображаются месяцы
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
Однако, как я уже сказал, месяцы не отображаются, если я пишу этот код.
Вот что я получаю, если пишу вышеприведенный код - CreateView
Как ограничить выбор иностранных ключей? Я просмотрел документацию Django, но не смог найти конкретного ответа на этот вопрос. Пожалуйста, помогите мне. Я искал много вопросов, связанных с этим, на stackoverflow и других сайтах. Не могли бы вы ответить на этот вопрос в данном контексте (пожалуйста, не отвечайте с общим кодом, так как я новичок в django и мне трудно понять общие ответы)
Заранее спасибо!
Проблема в том, что get_form_kwargs в вашем представлении:
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
Если вы print(self.kwargs.get('month_year_id')), то это будет None.
self.kwargs - это аргументы ключевого слова URL, которые вы предоставляете представлению, в вашем случае ваш url предоставляет два аргумента pk и pk2 здесь:
path('year/<int:pk>/<int:pk2>/create_expense/',views.ExpensesCreateView.as_view(),name ='create_expense'),
Итак, у вас есть два варианта, либо переименовать аргумент в пути, чтобы он был <int:month_year_id> (я не уверен, нужно ли переименовывать pk или pk2 только из ваших фрагментов кода).
или
В get_form_kwargs получите либо pk, либо pk2 из self.kwargs вместо month_year_id, например:
kwargs.update({'month_year_id': self.kwargs.get('pk2')})