@IvanGeso
Релейщик

Как правильнее всего сделать вложенную форму в Django 2?

Всем доброго времени суток. Делаю свой первый Django-проект и застрял на казалось бы простой штуке: имеется форма размещения заказа. Каждый заказ относится к одной или нескольким категориям. Я сделал функционал создания заказов и категорий. И теперь хочу сделать так, чтобы в форме создания заказа можно было на лету вызвать форму создания новой категории и создать ее, если это требуется. Собственно такая схема реализована в админке моего проекта (при нажатии на плюсик появляется форма создания категории): 5ca5bb6aed467412543323.png
Подскажите, как можно повторить такое поведение в моей форме? Я копал в сторону Inline formsets, однако как в документации, так и на просторах гугла пока не нашел ответа, как именно реализовать такое поведение. К тому же как я понял с отношением Many to Many этот способ на сработает. Также пробовал также как предлагается в данной статье: , однако это тоже не привело к желаемому результату. Пришлось вернуться к исходной точке, где создание заказа и категории обрабатывается в разных view.
Вот фрагменты кода:
# models.py

class ActiveOrder(models.Model):
    ...  # тут другие поля, не относящиеся к вопросу
    category = models.ManyToManyField('Category',
                                      blank=True,
                                      related_name='orders',
                                      verbose_name='Выбор категории')

class Category(models.Model):
    .... 
    category = models.CharField(max_length=80, verbose_name='Категория')


# views.py

class OrderCreate(View):
    def get(self, request):
        form = OrderForm()
        data = {'title': 'Создание нового заказа',
                'form': form,
                }
        return render(request, 'create_order.html', context=data)

    def post(self, request):
        bound_form = OrderForm(request.POST, request.FILES)
        data = {'title': 'Создание нового заказа',
                'form': bound_form,
                }
        if bound_form.is_valid():
            new_order = bound_form.save()
            return redirect(new_order)
        return render(request, 'create_order.html', context=data)

class CategoryCreate(View):
    def get(self, request):
        form = CategoryForm
        data = {'title': 'Создание новой категории',
                'form': form,
                }
        return render(request, 'create_cat.html', context=data)

    def post(self, request):
        bound_form = CategoryForm(request.POST, request.FILES)
        if bound_form.is_valid():
            new_cat = bound_form.save()
            return redirect(new_cat)
        data = {'title': 'Создание новой категории',
                'form': bound_form,
                }
        return render(request, 'create_cat.html', context=data)


# forms.py

class OrderForm(forms.ModelForm):

    class Meta:
        model = ActiveOrder
        fields = [... # тут другие поля формы
                  'category',
                  ]

        widgets = {... # тут другие поля формы
                   'category': forms.SelectMultiple(attrs={'class': 'form-control'}),
                   }
       ...  # clean-методы, не относящиеся к вопросу


class CategoryForm(forms.ModelForm):
    class Meta:
        model = Category
        fields = ['category', 'slug']
        widgets = {'slug': forms.HiddenInput(),
                   'category': forms.TextInput(attrs={'class': 'form-control'})}
       ... # тут clean-методы, не относящиеся к вопросу

Буду очень признателен за любую помощь (советы по кривости кода или его оформлению также приветствую)
  • Вопрос задан
  • 387 просмотров
Пригласить эксперта
Ответы на вопрос 1
@776166
Ну как бы это разные вещи.
Если вам в процессе создания объекта нужна новая категория, то вы сначала добавляете её, потом обновляете форму объекта и едете дальше.
Технически это можно сделать по-разному. Например, после создания категории перееаяксить поле с категориями. Или перезагрузить форму целиком, но там свои ньюансы.
Как костыль можно добавить поля с новыми категориями прямо в форму создания объекта и при сабмите обрабатывать. Но я бы не стал так делать.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы