Данные request.POST не содержатся в очищенных данных формы

При создании нового экземпляра моей модели мне не удается передать данные из request.POST в метод формы clean на is_valid():

class cView(TemplateView):
    template_name = "store/new_product.html"

    def post(self, request, *args, **kwargs):
        print(request.POST) # correctly prints <QueryDict: {'number': ['8'], 'name': ['myproduCT'], 'price': ['2']}>
        obj = Product.objects.create(number = request.POST["number"], data = {})
        form = ProductForm(request.POST, product = obj)
        form.is_valid() # validates to True

Форма выглядит следующим образом:

class ProductForm(forms.Form):
    class Meta:
        model = Product
        fields = ["id", "number", "data"]

    def __init__(self, *args, **kwargs):
        product = kwargs.pop("product")
        super().__init__(*args, **kwargs)
        self.fields["number"] = forms.IntegerField(required = True)
        for key in product.data.keys():
            self.fields[key] = forms.Charfield(requiered = False)

    def clean(self):
        cleaned_data = super().clean()
        print(cleaned_data) # only prints {'number': 8}
        ... 

Почему остальные данные request.POST отсутствуют в cleaned_data? Это происходит потому, что метод формы __init__() получает пустой атрибут product.data? Как мне избежать этого, если Product только что создан и не заполнен (проверенными) данными?

Продукт выглядит следующим образом:

class Product(models.Model):
    data = models.JSONField()
    number = models.PositiveIntegerField()

При создании динамических полей в вашей форме вы выполняете итерацию над пустым dict. Как вы сказали в своем сообщении, при создании объекта product данные пусты. Поэтому созданная вами форма содержит только числовое поле и не содержит полей для хранения других данных.

При инициализации формы с помощью request.POST, как в вашем коде, данные request.POST передаются в качестве первого аргумента в __init__ вашей формы. Вы можете использовать эти данные для создания вашей формы, например:

def __init__(self, *args, **kwargs):
   data = dict(args[0])
   data.pop('number')
   data.pop('csrfmiddlewaretoken')
   super().__init__(*args, **kwargs)
   self.fields["number"] = forms.IntegerField(required = True)
   for key in data.keys():
       self.fields[key] = forms.CharField(required = False)
Вернуться на верх