Данные 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)