Django 3.2 formsets - как отфильтровать продукт по списку компонентов, принадлежащих этому продукту?

Я пытаюсь создать набор форм, в котором пользователь сможет сделать следующее:

  1. Нажмите на кнопку и отобразите набор форм, относящийся к данному продукту. Я хочу отобразить все продукты и все компоненты после загрузки страницы, чтобы пользователь видел, какие компоненты относятся к каким продуктам.
  2. После того, как пользователь выберет продукт, набор форм расширится и пользователь сможет указать количество единиц измерения.
  3. После вставки всех единиц измерения во все формы пользователь должен нажать кнопку 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)
Вернуться на верх