Django UpdateView Два отдельных сохранения формы (включена inlineformset_factory)

У меня есть конкретная проблема с моими формами. Я думаю, будет лучше поделиться своими кодами вместо того, чтобы подробно объяснять проблему.

Вкратце объясню: внутри моей модели есть поле OneToOneField и модель этого поля имеет форму inlineformset_factory. Моя новая модель также имеет форму, и я хочу сохранить обе формы.

Когда я хочу сохранить форму обновления предложения, я получаю следующую ошибку:

TypeError at /ru/mytarget/offer-update/T2GTTT053E9/

AdminOfferUpdateView.form_invalid() отсутствуют 2 обязательных позиционных аргумента: 'request_form' и 'request_item_formset'

Модели:

request.py

class RequestModel(models.Model):
    customer = models.ForeignKey(Customer, on_delete=models.CASCADE, related_name="customer_requests")
    id = ShortUUIDField(primary_key=True, length=10, max_length=10, prefix="T", alphabet="ARGET0123456789", unique=True, editable=False)
    status = models.BooleanField(default=True)
    request_title = models.CharField(max_length=300)
    delivery_time = models.CharField(max_length=50)
    shipping_country = models.CharField(max_length=50)
    shipping_address = models.CharField(max_length=300)
    preferred_currency = models.ForeignKey(Currency, on_delete=models.CASCADE)
    shipping_term = models.ForeignKey(ShippingTerm, on_delete=models.CASCADE)
    delivery_term = models.ForeignKey(DeliveryTerms, on_delete=models.CASCADE)
    request_statuses = models.ForeignKey(RequestStatus, on_delete=models.CASCADE, blank=True, default=1)
    is_accepted = models.BooleanField(default=False)
    is_rejected = models.BooleanField(default=False)
    is_offer_created = models.BooleanField(default=False)
    updated_on = models.DateTimeField(auto_now=True)
    published_date = models.DateTimeField(default=timezone.now)

    def __str__(self):
        return str(self.request_title)

    class Meta:
        verbose_name_plural = "Requests"
        verbose_name = "Request"

    def get_absolute_url(self):
        return reverse('mytarget:customer_request_details', kwargs={'pk': self.id})


class RequestItem(models.Model):
    request_model = models.ForeignKey(RequestModel, on_delete=models.CASCADE, related_name="request_items")
    product_name = models.CharField(max_length=300)
    product_info = models.TextField(max_length=2000, blank=True)
    target_price = models.DecimalField(max_digits=15, decimal_places=2, blank=True, null=True)
    price = models.DecimalField(max_digits=15, decimal_places=2, blank=True, null=True)
    quantity = models.DecimalField(max_digits=10, decimal_places=2)

    dimensions = models.CharField(max_length=100, blank=True)
    net_weight = models.CharField(max_length=20, blank=True)
    gross_weight = models.CharField(max_length=20, blank=True)
    hs_or_tn_ved_code = models.CharField(max_length=100, blank=True)
    brand = models.CharField(max_length=100, blank=True)
    manufacturer = models.CharField(max_length=100, blank=True)
    origin_country = models.CharField(max_length=50, blank=True)
    manufacturer_address = models.CharField(max_length=300, blank=True)

offer.py

Формы:

request_create_form.py

offer_update_form.py

Просмотров:

offer_update_view.py

@method_decorator([login_required(login_url=reverse_lazy("accounts:signin")), user_is_superuser], name='dispatch')
class AdminOfferUpdateView(UpdateView):
    model = OfferModel
    form_class = AdminOfferUpdateForm
    template_name = "mytarget/admin_offer_update.html"

    def get_context_data(self, **kwargs):
        context = super(AdminOfferUpdateView, self).get_context_data(**kwargs)
        if self.request.POST:
            context['request_form'] = AdminOfferUpdateForm(self.request.POST, instance=self.object.request_model_name)
            context['request_item_formset'] = RequestItemInlineFormset(self.request.POST, instance=self.object.request_model_name)
        else:
            context['request_form'] = AdminOfferUpdateForm(instance=self.object.request_model_name)
            context['request_item_formset'] = RequestItemInlineFormset(instance=self.object.request_model_name)
        return context

    def form_valid(self, form):
        context = self.get_context_data()
        request_form = context['request_form']
        request_item_formset = context['request_item_formset']
        with transaction.atomic():
            self.object = form.save()
            if request_form.is_valid() and request_item_formset.is_valid():
                request_form.instance = self.object.request_model_name
                request_form.save()
                request_item_formset.instance = self.object.request_model_name
                request_item_formset.save(commit=False)
                for ri in request_item_formset:
                    ri.save(commit=False)
                    request_item_formset.save()
        return super(AdminOfferUpdateView, self).form_valid(form)

    def form_invalid(self, form, request_form, request_item_formset):
        return self.render_to_response(
            self.get_context_data(form=form, request_form=request_form, request_item_formset=request_item_formset)
        )

    def get_initial(self):
        self.object = self.get_object()
        if self.object:
            return {"request_model": self.object.request_model_name, "request_item_formset": self.object.request_model_name}
        return super().initial.copy()

    def get_success_url(self):
        return reverse('mytarget:admin_offer_update', kwargs={'pk': self.object.id})

Я решил свою проблему. Я создал функцию кнопки, которая создает новую модель с наследованием полей другой модели. Таким образом, нет необходимости редактировать форму другой модели внутри формы моей текущей модели.

Вернуться на верх