Есть вот такие модели
class Order(models.Model):
number = models.CharField('Код заказа', max_length=12)
date = models.DateField('Дата создания', default=datetime.now)
deadline = models.DateField('Срок изготовления')
worth = models.DecimalField('ИТОГО', max_digits=10, decimal_places=2)
prepayment = models.DecimalField('Предоплата', max_digits=10, decimal_places=2)
check_img = models.ImageField(upload_to='orders/%Y/%m/%d', blank=True)
city = models.ForeignKey(City, on_delete=PROTECT, default=1)
saloon = models.ForeignKey(Saloon, on_delete=PROTECT)
user = models.ForeignKey(User, on_delete=PROTECT, default=1)
client = models.ForeignKey(Client, on_delete=PROTECT)
furniture = models.ManyToManyField(Furniture, through='OrderItem')
class Meta:
db_table = 'order'
verbose_name = "Заказ"
verbose_name_plural = "Заказы"
def __str__(self):
return self.worth
class OrderItem(models.Model):
order = models.ForeignKey(Order, on_delete=PROTECT)
furniture = models.ForeignKey(Furniture, on_delete=PROTECT)
seat_len = models.PositiveIntegerField('Длина сиденья')
seat_deep = models.PositiveIntegerField('Глубина сиденья')
back_len = models.PositiveIntegerField('Длина спинки')
back_deep = models.PositiveIntegerField('Глубина спинки')
otto_len = models.PositiveIntegerField('Длина оттоманки')
otto_deep = models.PositiveIntegerField('Глубина оттоманки')
quantity = PositiveIntegerField()
tex1 = models.ForeignKey(Tex, default=1, on_delete=PROTECT, related_name='tex1')
tex2 = models.ForeignKey(Tex, default=1, on_delete=PROTECT, related_name='tex2')
def __str__(self):
return f'Id: {self.pk }, {self.furniture} for OrderId: {self.order.pk}'
class Meta:
db_table = 'order_item'
verbose_name = "Позиция заказа"
verbose_name_plural = "Позиции заказа"
Вот такие формы
class OrderItemForm(ModelForm):
furniture = ModelChoiceField(queryset=Furniture.objects.all(), empty_label='Модель не выбрана', label='Модель')
tex1 = ModelChoiceField(queryset=Tex.objects.all(), empty_label='Ткань не выбрана', label='Основная ткань')
tex2 = ModelChoiceField(queryset=Tex.objects.all(), empty_label='Ткань не выбрана', label='Ткань компаньон')
class Meta:
model = OrderItem
fields = ['furniture', 'tex1', 'tex2', 'seat_len', 'seat_deep', 'back_len', 'back_deep', 'otto_len', 'otto_deep', 'quantity']
widgets = {
'furniture': TextInput(attrs={
'class': 'form-control',
'placeholder': 'Модель'
}),
'tex1': TextInput(attrs={
'class': 'form-control',
'placeholder': 'Основная ткань'
}),
'tex2': TextInput(attrs={
'class': 'form-control',
'placeholder': 'Ткань компаньон'
}),
'seat_len': TextInput(attrs={
'class': 'form-control',
'placeholder': 'Изменение длины сиденья'
}),
'seat_deep': TextInput(attrs={
'class': 'form-control',
'placeholder': 'Изменение глубины сиденья'
}),
'back_len': TextInput(attrs={
'class': 'form-control',
'placeholder': 'Изменение длины спинки'
}),
'back_deep': TextInput(attrs={
'class': 'form-control',
'placeholder': 'Изменение ширины спинки'
}),
'otto_len': TextInput(attrs={
'class': 'form-control',
'placeholder': 'Изменение длины оттоманки'
}),
'otto_deep': TextInput(attrs={
'class': 'form-control',
'placeholder': 'Изменение глубины оттоманки'
}),
'quantity': TextInput(attrs={
'class': 'form-control',
'placeholder': 'Количество в заказе'
})
}
OrderItemInlineFormset = inlineformset_factory(Order, OrderItem, form=OrderItemForm, extra=5)
class OrderForm(ModelForm):
client = ModelChoiceField(queryset=Client.objects.all(), empty_label='Клиент не выбран', label='Клиент')
saloon = ModelChoiceField(queryset=Saloon.objects.all(), empty_label='Салон не выбран', label='Салон')
class Meta:
model = Order
fields = ['number', 'deadline', 'client', 'saloon', 'worth', 'prepayment']
widgets = {
'number': TextInput(attrs={
'class': 'form-control',
'placeholder': 'Номер заказа'
}),
'deadline': TextInput(attrs={
'class': 'form-control',
'type': 'date',
'placeholder': 'Срок'
}),
'client': TextInput(attrs={
'class': 'form-control',
'type': 'input-group-text',
'placeholder': 'Клиент'
}),
'saloon': TextInput(attrs={
'class': 'form-control',
'placeholder': 'Салон'
}),
'worth': TextInput(attrs={
'class': 'form-control',
'placeholder': 'Общая сумма заказа'
}),
'prepayment': TextInput(attrs={
'class': 'form-control',
'placeholder': 'Предоплата'
})
}
Вот такое представление для создания заказа:
class orderCreateView(CreateView):
form_class = OrderForm
success_url = '/orders/orders/'
template_name = 'orders/orders/orderCreate.html'
def get_context_data(self, **kwargs):
context = super(orderCreateView, self).get_context_data(**kwargs)
context['order_item_formset'] = OrderItemInlineFormset()
return context
def post(self, request, *args, **kwargs):
self.object = None
form_class = self.get_form_class()
form = self.get_form(form_class)
order_item_formset = OrderItemInlineFormset(self.request.POST)
if form.is_valid() and order_item_formset.is_valid():
return self.form_valid(form, order_item_formset)
else:
return self.form_invalid(form, order_item_formset)
def form_valid(self, form, order_item_formset):
self.object = form.save(commit=False)
self.object.save()
# saving OrderItems Instances
order_metas = order_item_formset.save(commit=False)
for meta in order_metas:
meta.order = self.object
meta.save()
return redirect(reverse("orders"))
def form_invalid(self, form, order_item_formset):
return self.render_to_response(
self.get_context_data(form=form,
order_item_formset=order_item_formset
)
)
Ну и шаблон
{% extends 'orders/layout.html' %}
{% block title %}Новый заказ{% endblock %}
{% block titleH1 %}Новый заказ{% endblock %}
{% block content %}
<form method="post">
{% csrf_token %}
<h1>Создание заказа</h1>
{{ form.non_form_errors }}
{{ form.as_p }}
<h5 class="text-info">Добавить позиции заказа</h5>
{{ order_item_formset.non_form_errors }}
{{ order_item_formset.management_form }}
<p>
<table border="1" bgcolor="white">
<thead bgcolor="#320C8F">
<th width="70">Модель</th>
<th width="60">Осн.ткань</th>
<th width="200">Компаньон</th>
<th width="30%">Кол-во</th>
<th width="100">Действие</th>
</thead>
{% for form in order_item_formset %}
<tr>
<td>{{ form.furniture }}</td>
<td>{{ form.tex1 }}</td>
<td>{{ form.tex2 }}</td>
<td>{{ form.quantity }}</td>
<td>{% if order_item_formset.can_delete %}
{{ form.DELETE }} {{ form.DELETE.label }}
{% endif %}
</td>
</tr>
{% endfor %}
</table>
</p>
<button type="submit" class="btn btn-warning">Добавить</button>
</form>
{% endblock %}
По нажатию кнопки "Добавить" поля формы с содержимым заказа очищаются, переход на страницу со списком заказов не осуществляется. Поля с номером заказа, данными заказчика и проч. остаются заполненными. А нужно, соответственно, сохранить заказ со всеми позициями.
Что я делаю не так, где ошибка?