Reputation: 21
I have a problem with filtering a queryset through a list of object ID's. Upon form submission, the error [{'item': ['Select a valid choice. That choice is not one of the available choices.']}]
shows up. When passing req
(a list of integers) into a filtered queryset, Django does not accept req
as a set of valid choices/objects and does not save the form. However, when passing a preset list that contains the same values as req
, Django accepts and saves the form. I tried printing if req
is equal to the same preset list and it returned True.
views.py
class TransferAddView(LoginRequiredMixin, generic.CreateView):
...
def form_valid(self, form, **kwargs):
ctx = self.get_context_data()
inlines = ctx['inlines']
form.instance.requisition = ctx['req']
if inlines.is_valid() and form.is_valid():
tran = form.save()
inlines.instance = tran
inlines.save()
return super(TransferAddView, self).form_valid(form)
def get_context_data(self, **kwargs):
ctx=super(TransferAddView,self).get_context_data(**kwargs)
ctx['req'] = MaterialRequisition.objects.get(pk=self.kwargs['req'])
req = list(MaterialRequisitionItems.objects.filter(requisition=ctx['req']).values_list('item', flat=True))
ctx['item'] = Item.objects.filter(item__in=req)
if self.request.method == 'POST':
ctx['form']=TransferModelForm(self.request.POST)
ctx['inlines']=TransferInlineFormSet(self.request.POST)
ctx['form'].fields['transferStatus'].initial = 0
else:
ctx['form']=TransferModelForm()
ctx['form'].fields['transferStatus'].initial = 0
ctx['inlines']=TransferInlineFormSet(form_kwargs={'req':ctx['req'].pk})
return ctx
forms.py
class TransferItemsModelForm(forms.ModelForm):
...
def __init__(self, *args, **kwargs):
req = kwargs.pop('req', None)
super(TransferItemsModelForm, self).__init__(*args, **kwargs)
...
req = list(MaterialRequisitionItems.objects.filter(requisition=req).values_list('item', flat=True))
self.fields['item'].queryset = Item.objects.filter(item__in=req)
Upvotes: 1
Views: 279
Reputation: 21
I may have figured out how to do this properly. I changed req
to reqs
then I passed reqs
into the formset in the POST method and tweaked it a little bit. Now the get_context_data
in the views look like this:
def get_context_data(self, **kwargs):
ctx=super(TransferAddView,self).get_context_data(**kwargs)
ctx['req'] = MaterialRequisition.objects.get(pk=self.kwargs['req'])
req = list(MaterialRequisitionItems.objects.filter(requisition=ctx['req']).values_list('item', flat=True))
ctx['item'] = Item.objects.filter(item__in=req)
if self.request.method == 'POST':
ctx['form']=TransferModelForm(self.request.POST)
ctx['inlines']=TransferInlineFormSet(self.request.POST, form_kwargs={'reqs': list(MaterialRequisitionItems.objects.filter(requisition=ctx['req'].pk).values_list('item', flat=True))})
ctx['form'].fields['transferStatus'].initial = 0
else:
ctx['form']=TransferModelForm()
ctx['form'].fields['transferStatus'].initial = 0
ctx['inlines']=TransferInlineFormSet(form_kwargs={'reqs': list(MaterialRequisitionItems.objects.filter(requisition=ctx['req'].pk).values_list('item', flat=True))})
return ctx
Upvotes: 1