Как добавить значение из поля ввода пользователя в библиотеке django imoirt-export?

У меня есть модель Product и Calculator, который связан с каждым элементом в модели Product.

Я пытаюсь добиться того, чтобы позволить пользователю вставить количество единиц товара и на основе этого количества рассчитать общую цену в файле Excel, который будет экспортирован, когда пользователь нажмет кнопку Calculate.

Вопросы:

  1. Как добавить значение, введенное пользователем в поле ввода, в файл cost_calculator.xlsx и на основе этого значения рассчитать общую цену?
  2. Как я могу добавить unit_hours свойство из CostCalculator модели в мой экспортированный файл? Я успешно добавил его на странице администратора, и оно показывает мне правильный результат, но когда я добавляю его к полям в модели ресурса, я получаю KeyError.
  3. Какой лучший подход для вычисления total_price и отображения его в Excel в моем случае? Формула выглядит следующим образом: number_of_units * rate * margin = total_price. Должен ли я поместить ее в form_valid в ProductDetailView или в ExportData в представлении или, может быть, я не должен отделять кнопку экспорта в отдельное представление, а добавить ее в form_valid.
  4. Возможно ли объединить кнопки Send и Calculate в одну, чтобы если пользователь нажмет на 1 кнопку, она отправляла значение пользователя, рассчитывала и экспортировала единицы_часов и общую_цену?

Предположения

  1. Мне нужно иметь калькулятор затрат в DetailView.
  2. Компоненты услуг должны быть разделены, потому что будет много одинаковых компонентов, которые я буду подключать к продуктам.

Ниже приведен мой код:

models.py

class Product(models.Model):
    title = models.CharField(max_length=400, default='')

class CalculatorServiceComponent(models.Model):
    service = models.CharField(max_length=500, default='', blank=True)
    product = models.ManyToManyField(Product, related_name='calculator_service_component_product', blank=True, default='-')
    component = models.CharField(max_length=500, default='', blank=True)

class CostCalculator(models.Model):
    related_product = models.ForeignKey(Product, on_delete=models.CASCADE, null=True, blank=True, related_name='related_product')
    title_component = models.ForeignKey(CalculatorServiceComponent, on_delete=models.CASCADE, default=1)
    weights = models.FloatField(default=0.0)
    total_hours = models.IntegerField(default=0)
    number_of_units = models.IntegerField(default=0) # this is the field that user will be adding and based on this value total_price will be calculated
    rate = models.IntegerField(default=0)
    margin = models.FloatField(default=0.0)
    
    def _unit_h(self):
        return self.weights * self.total_hours
    unit_hours = property(_unit_h)

forms.py

class CalculatorForm(forms.ModelForm):
    number_of_units = forms.IntegerField(help_text='Only numeric values are allowed.', min_value=0)
    
    class Meta: 
        model = CostCalculator
        fields = ('number_of_units',)

resources.py

class CostCalculatorResource(resources.ModelResource):
    class Meta:
        model = CostCalculator
        fields = ('id', 'title_component__service', 'related_product__title', 'title_component__component', 'weights', 'weights', 'total_hours', 'unit_hours')

views.py

class ProductDetailView(LoginRequiredMixin, FormMixin, DetailView):
    login_url = 'login'
    redirect_field_name = 'login'
    template_name = 'ProductDetailView.html'
    model = Product
    form_class = CalculatorForm
    date_field = "publish"
    month_format = "%m"
    
    def get_context_data(self, **kwargs):
            context = super(ProductDetailView, self).get_context_data(**kwargs)
            form = CalculatorForm(initial={'obj': self.object})

            context['form'] = form
            return context
        
    def post(self, request, *args, **kwargs):
            self.object = self.get_object()
            form = self.get_form()
            if form.is_valid():
                return self.form_valid(form)
            else:
                return self.form_invalid(form)

    def form_valid(self, form):
        title_component = CostCalculator.objects.filter(related_product__slug=self.kwargs['slug'])
        unit_hours = form.cleaned_data['weights'] * form.cleaned_data['total_hours'] # how can I pass this to my ExportData class?
        form.save()
        return super(ProductDetailView, self).form_valid(form)

    def get_success_url(self):
        return reverse('product', kwargs={'slug': self.kwargs['slug']})


class ExportData(LoginRequiredMixin, View):

    def get(self, _unit_h, *args, **kwargs ):
        filter_qs = CostCalculator.objects.filter(related_product__slug=self.kwargs['slug'])
        dataset = CostCalculatorResource().export(filter_qs)
        response = HttpResponse(dataset.xlsx, content_type="xlsx")
        response['Content-Disposition'] = 'attachment; filename=cost_calculator.xlsx'
        return response

ProductDetailView.html

{% for component in calculator_components.all %}
<div class="collapse py-2" id="component{{component.id}}">
    <h3 class="fw-bold">{{component.title_component}}:</h3>
    <form method="post" enctype="multipart/form-data" class="w-25">
        {% csrf_token %}
        {{ form|crispy }}
        <button type="submit" class="btn bg-hubble">Send</button>
        </form>
</div>
{% endfor %}
<a href="{% url 'export_calculator' product.slug %}"><button type="button" class="btn">Calculate</button></a>
Вернуться на верх