问题描述
我在 inlineformset 中创建了一个 Class Based(CreateView)。我需要将 request.user
传递给表单以在表单字段之一上启用过滤器功能。但是,我在线上收到一个 Key Error: request
:
self.request = kwargs.pop('request')
在表单的 def __init__(self,*args,**kwargs):
中。将不胜感激。
也欢迎有关我的编程的提示。
models.py:
class ttransactions(models.Model):
transaction_type = models.CharField(max_length=10,choices=tx_choices)
description = models.CharField(max_length=50,null=False,blank=False,default='Description')
transaction_date = models.DateField(default=datetime.today,db_index=True)
company = models.ForeignKey(tcompany,on_delete=models.PROTECT,db_index=True)
def __str__(self):
return self.description
class ttransaction_lines(models.Model):
transaction = models.ForeignKey(ttransactions,on_delete=models.CASCADE,db_index=True)
sequence = models.IntegerField()
transaction_type = models.CharField(max_length=6,choices=debit_credit)
ledger_account = models.ForeignKey(tledger_account,db_index=True)
amount = models.DecimalField(max_digits=14,decimal_places=2,default=0.0)
quantity = models.IntegerField(blank=True,null=True)
posted = models.BooleanField(default=True)
forms.py:
class TransactionLinesForm(forms.ModelForm):
class Meta:
model = ttransaction_lines
fields = ['transaction_type','ledger_account','amount']
def __init__(self,**kwargs):
self.request = kwargs.pop('request')
super(TransactionLinesForm,self).__init__(*args,**kwargs)
user = self.request.user
current_company = user.current_company
self.fields['ledger_account'].queryset = tledger_account.objects.filter(
company=current_company)
TransactionLineFormset = inlineformset_factory(ttransactions,ttransaction_lines,# fields=['transaction_type','amount'],form=TransactionLinesForm,can_order=True,can_delete=True)
views.py:
class JournalCreateView(LoginrequiredMixin,CreateView):
template_name = 'accounting/journal.html'
model = ttransactions
transaction_lines_form = TransactionLineFormset
form_class = TransactionsForm
success_url = '/accounting/transaction_list'
def get_form_kwargs(self):
kwargs = super(JournalCreateView,self).get_form_kwargs()
kwargs['request'] = self.request
return kwargs
def get(self,request,**kwargs):
self.object = None
form_class = self.get_form_class()
form = self.get_form(form_class)
transaction_lines_form = TransactionLineFormset()
return self.render_to_response(
self.get_context_data(form=form,transaction_lines_form=transaction_lines_form))
def post(self,**kwargs):
extra_forms = 1
if 'additems' in request.POST and request.POST['additems'] == 'true':
formset_dictionary_copy = self.request.POST.copy()
formset_dictionary_copy['form-TOTAL_FORMS'] = \
int(formset_dictionary_copy['form-TOTAL_FORMS']) + extra_forms
transaction_lines_form = TransactionLinesFormSet(formset_dictionary_copy)
return self.render_to_response(
self.get_context_data(form=form,transaction_lines_form=transaction_lines_form))
self.object = None
form_class = self.get_form_class()
form = self.get_form(form_class)
transaction_lines_form = TransactionLineFormset(self.request.POST)
if (form.is_valid() and transaction_lines_form.is_valid()):
return self.form_valid(form,transaction_lines_form)
else:
return self.form_invalid(form,transaction_lines_form)
def form_valid(self,form,transaction_lines_form):
form.instance.company = self.request.user.current_company
self.object = form.save()
sequence = 1
for line in transaction_lines_form:
line.instance.sequence = sequence
sequence += 1
transaction_lines_form.instance = self.object
transaction_lines_form.save()
return super().form_valid(form)
def form_invalid(self,transaction_lines_form):
return self.render_to_response(
self.get_context_data(form=form,transaction_lines_form=transaction_lines_form))
解决方法
您的表单可能在多个地方被初始化。如果没有看到回溯,很难找到错误发生的地方。
因此,最好将过滤逻辑保留在视图中,而不是将“请求”传递给表单。删除表单中的 __init__
方法并在视图中尝试以下代码
def get(self,request,*args,**kwargs):
self.object = None
form_class = self.get_form_class()
form = self.get_form(form_class)
transaction_lines_form = TransactionLineFormset()
transaction_lines_form.form.base_fields['ledger_account'].queryset = \
tledger_account.objects.filter(company=request.user.current_company)
return self.render_to_response(
self.get_context_data(form=form,transaction_lines_form=transaction_lines_form))