Django formset queryset
У меня есть два приложения: бухгалтерия и проекты.
Каждый предмет потребления имеет fk к проекту. Каждое производство имеет fk к проекту.
Производственный заказ имеет fk к производству. произведенный продукт имеет fk к производственному заказу. предмет потребления имеет fk к произведенному продукту.
При создании производственной линии я хочу создать линию потребления в виде набора форм. Однако в поле consumptionitemline_to_consume должны отображаться экземпляры из связанного проекта, а не все экземпляры. Ниже я попытался отфильтровать выпадающий список, но это просто не работает.
Здесь есть формы
class ProductionProducedLineConsumptionLineForm(forms.ModelForm):
class Meta:
model = ProductionProducedLineConsumptionLine
fields = '__all__'
widgets = {
'productionproducedline': forms.HiddenInput(),
'produced_kg_scrap': forms.NumberInput(attrs={'class': 'w-full input rounded-md'}),
'produced_kg_wastage': forms.NumberInput(attrs={'class': 'w-full input rounded-md'}),
}
def __init__(self, *args, **kwargs):
production_id = kwargs.pop('production_id', None) # We'll pass this when initializing the formset in the view
super(ProductionProducedLineConsumptionLineForm, self).__init__(*args, **kwargs)
if production_id:
production = ProductionProducedLine.objects.get(id=production_id)
project = production.productionorderline.production.project
self.fields['consumptionitemline_to_consume'].queryset = ConsumptionItemLine.objects.filter(project=project) # This does not work?
ProductionProducedLineConsumptionLineFormSet = inlineformset_factory(
ProductionProducedLine,
ProductionProducedLineConsumptionLine,
fk_name='productionproducedline',
form=ProductionProducedLineConsumptionLineForm, # Use the custom form
fields=('productionproducedline','productionproducedline_to_consume', 'consumptionitemline_to_consume','consumed_kg_product','produced_kg_scrap', 'produced_kg_wastage','wastage_return_customer'),
extra=1,
can_delete=True
)
Вот вид
class ProductionProducedLineCreateView(CreateView):
model = ProductionProducedLine
form_class = ProductionProducedLineForm
template_name = 'projects/produced_create.html'
def get_form_kwargs(self):
"""Ensure the form is initialized with necessary kwargs."""
kwargs = super(ProductionProducedLineCreateView, self).get_form_kwargs()
if self.kwargs.get('order_line_id'):
kwargs['order_line_id'] = self.kwargs['order_line_id']
return kwargs
def get_context_data(self, **kwargs):
"""Add formset to context data for rendering in the template."""
context = super(ProductionProducedLineCreateView, self).get_context_data(**kwargs)
order_line_id = self.kwargs.get('order_line_id')
if order_line_id:
order_line = ProductionOrderLine.objects.get(pk=order_line_id)
context['order_line'] = order_line
context['production'] = order_line.production
context['project'] = order_line.production.project
if self.request.POST:
context['formset'] = ProductionProducedLineConsumptionLineFormSet(self.request.POST, self.request.FILES)
else:
context['formset'] = ProductionProducedLineConsumptionLineFormSet()
return context
def post(self, request, *args, **kwargs):
"""Handle POST requests: Validate both form and formset."""
self.object = None # This is required for CreateView to correctly instantiate the form
form = self.get_form()
formset = ProductionProducedLineConsumptionLineFormSet(self.request.POST, self.request.FILES)
if form.is_valid() and formset.is_valid():
return self.form_valid(form, formset)
else:
return self.form_invalid(form, formset)
def form_valid(self, form, formset):
"""If the form and formset are valid, save the associated models."""
self.object = form.save() # Save the ProductionProducedLine instance
formset.instance = self.object # Link the formset with the instance
formset.save() # Save the formset data
return redirect(self.get_success_url()) # Redirect to a success page
def form_invalid(self, form, formset):
return self.render_to_response(self.get_context_data(form=form, formset=formset))
def get_success_url(self):
"""Return the URL to redirect to after successful processing."""
# Adjust this to wherever you want users to be redirected after a successful creation
return reverse('production-list')
Я только что проиграл. Любая помощь будет оценена по достоинству.