Django 3.2 formsets - как отфильтровать продукт по списку компонентов, принадлежащих этому продукту?
Я пытаюсь создать набор форм, в котором пользователь сможет сделать следующее:
- Нажмите на кнопку и отобразите набор форм, относящийся к данному продукту. Я хочу отобразить все продукты и все компоненты после загрузки страницы, чтобы пользователь видел, какие компоненты относятся к каким продуктам.
- После того, как пользователь выберет продукт, набор форм расширится и пользователь сможет указать количество единиц измерения.
- После вставки всех единиц измерения во все формы пользователь должен нажать кнопку Submit и все формы должны быть сохранены одновременно.
ВОПРОС:
Как связать компоненты в каждом наборе форм с кнопкой, чтобы после разворачивания она показывала компоненты, относящиеся только к этому продукту. Мне удалось отфильтровать компоненты путем создания цикла в моем первоначальном методе, но я не уверен, как сделать его динамическим.
Моя идея заключалась в том, чтобы как-то отфильтровать все компоненты в каждом продукте на основе значения slug продукта в атрибуте data-bs-target
, но я не уверен, как это сделать.
Мой второй вопрос - как я могу сделать 1 набор форм, чтобы пользователю нужно было нажать кнопку submit только один раз?
class CostCalculatorView(TemplateView):
template_name = "cost_calculator.html"
def get(self, *args, **kwargs):
product_list = Product.objects.all()
get_components = CostCalculator.objects.filter(related_product__title=product_list[0]) # how to make it dynamic?
get_datetime = timezone.now().strftime('%Y-%m-%dT%H:%M:%S')
formset = CalculatorFormset(initial=[{
'author': self.request.user.email,
'related_product': component.related_product,
'related_component': component.id,
'created': get_datetime,
'number_of_units': 0
} for component in get_components])
return self.render_to_response({'calculator_formset': formset, 'product_list': product_list})
def post(self, *args, **kwargs):
formset = CalculatorFormset(data=self.request.POST)
if formset.is_valid():
for form in formset:
form.save()
return super().form_valid(form)
calculator.html
<section class="container">
{% for product in product_list %}
<p>
<button type="button" data-bs-toggle="collapse" data-bs-target="#{{product.slug}}" aria-expanded="false" aria-controls="{{product.slug}}">
{{product.title}}
</button>
</p>
<div class="collapse" id="{{product.slug}}">
<form id="form-container" method="POST">
{% csrf_token %}
{{calculator_formset.management_form}}
{% for form in calculator_formset %}
<div class="calculator-form pt-2">
{{form.as_table}}
</div>
{% endfor %}
<button type="submit" class="cost-calculator">Submit</button>
</form>
</div>
{% endfor %}
</section>
forms.py
class CalculatorForm(forms.ModelForm):
author = forms.CharField(widget = forms.HiddenInput(), required = False)
created = forms.DateTimeField(widget = forms.HiddenInput(), required = False)
number_of_units = forms.IntegerField(min_value=0)
total_price = forms.IntegerField(widget = forms.HiddenInput(), required = False)
class Meta:
model = CERequest
fields = ('author', 'created', 'related_product', 'related_component', 'number_of_units')
CalculatorFormset = formset_factory(CalculatorForm, extra=0, can_delete=False)
models.py
class Product(models.Model):
title = models.CharField(max_length=254)
slug = models.SlugField(max_length=254)
class CostCalculator(models.Model):
related_product = models.ForeignKey(Product, on_delete=models.CASCADE)
component_name = models.CharField(max_length=254, default='')
class CERequest(models.Model):
author = models.CharField(max_length=255, blank=True, null=True)
related_component = models.ForeignKey(CostCalculator, on_delete=models.CASCADE)
number_of_units = models.IntegerField(default=0)
related_product = models.ForeignKey(Product, on_delete=models.CASCADE)
created = models.DateTimeField(default=timezone.now)
total_price = models.IntegerField(default=0, blank=True, null=True)