Или нет…
Продолжаю бороться с этими формами((На одной странице есть 2 формы.
Есть 2 модели: 1. Product. 2. SpeciallyPrice. SpeciallyPrice связан через FK с Product. В то же время, SpecialPrice является InlineModel в Product.
Поля формы SpecialPriceForm автоматически создаются суриптом JS. То есть их может быть n-ное колличествоо. Необходимо создать запись для каждого такого срабатывания скрипта. В принципе, я догадываюсь, как это сделать - использовать цикл для списка полученных значений. Но проблема в том, что я не могу получить этот список. По какой-то причине из формы приходит None.
class ProductsCreate(CreateView):
model = Product
form_class = ProductCreateForm
http_method_names = ['get', 'post']
def get_initial(self):
initial = super(ProductsCreate, self).get_initial()
initial['request'] = self.request
return initial
def get_context_data(self, *args, **kwargs):
ctx=super(ProductsCreate, self).get_context_data(*args, **kwargs)
ctx['special_form'] = SpeciallyPriceForm()
return ctx
def get(self, request, *args, **kwargs):
self.object = None
if kwargs.get('slug'):
category = Category.objects.filter(slug=kwargs.get('slug')).first()
self.initial.update({'category': category})
return self.render_to_response(self.get_context_data())
def post(self, request, *args, **kwargs):
self.object = None
form = ProductCreateForm(request.POST, request.FILES, initial={'request': request})
special_form = SpeciallyPriceForm(request.POST)
print(special_form) #Пустая форма, но валидна. Как?
if form.is_valid() and special_form.is_valid():
return self.form_valid(form, special_form)
else:
return self.form_invalid(form, special_form)
def form_valid(self, form, special_form):
product = form.save(commit=False)
product.user = self.request.user
product.save()
for cat in form.cleaned_data.get('category'):
product.category.add(cat)
for paym in form.cleaned_data.get('payment_method'):
product.payment_method.add(paym)
for distr in form.cleaned_data.get('distribution_type'):
product.distribution_type.add(distr)
#Здесь я думал под каждый элемент списка создавать запись, связанную с созданным продуктом. Верна ли логика?
special = special_form.save(commit=False)
special.product = product
special.save()
for spec_price in special_form.cleaned_data.get('adittional_specially_price'):
print(spec_price)
special.adittional_specially_price = spec_price
for spec_numb in special_form.cleaned_data.get('adittional_specially_number'):
print(spec_numb)
special.adittional_specially_number = spec_numb
class ProductCreateForm(forms.ModelForm):
#...
class SpeciallyPriceForm(forms.ModelForm):
class Meta:
model = SpeciallyPrice
fields = ['adittional_specially_price', 'adittional_specially_number']
def clean(self):
cleaned_data = super(SpeciallyPriceForm, self).clean()
cd_adittional_specially_price = cleaned_data.get('adittional_specially_price')
print(cd_adittional_specially_price) #None
cd_adittional_specially_number = cleaned_data.get('adittional_specially_number')
print(cd_adittional_specially_number) #None
Шаблон Джанго + скрипт
<html><body>
Special price from {{ special_form.adittional_specially_price }} kg {{ special_form.adittional_specially_number }} usd
<script>
(function(){
var copy = document.querySelector('.field.inline.specially').cloneNode(true);
document.querySelector('html').addEventListener('input', function(e){
if(e.target.classList.contains('event') && e.target.tagName == 'INPUT'){
var error = 0;
for(var evt of document.querySelectorAll('.field.inline.specially input.event')){
evt.value = evt.value.replace(/[^\d]/,'');
if(!evt.value || +evt.value < 1) error++;
}
if(!error){
var last = document.querySelectorAll('.field.inline.specially');
last[last.length-1].insertAdjacentHTML('afterEnd', copy.outerHTML);
}
}
});
})();
</script>
</body></html>
Когда я пытался посмотреть во views эту форму, получал просто пустаю форму вроде этой. Но почему она валидна, Карл?
<label for="specially" class="subhead">Special price from</label>
<span class="id_specially_price"><input type="text" name="adittional_specially_price" style="width: 165px" class="event" id="id_adittional_specially_price"></span>
<span>kg</span>
<span class="id_specially_number"><input type="text" name="adittional_specially_number" style="width: 100px" class="event" id="id_adittional_specially_number"></span>
<span>usd</span>
Может быть, это нужно решать через Ajax, как-то обрабатывать запрос? Или есть какой-то “джанговский” способ?
Как вариант, я думаю, что во views показны только последние два поля, которые остаются пустыми. Но в этом я не уверен. Я тут, кстати, ещё заметил, что айдишник у созданных полей у инпутов повторяются. Возможно, в этом и есть баг…