I
I
Ivan Zhuravlev2019-04-04 11:27:07
Django
Ivan Zhuravlev, 2019-04-04 11:27:07

What is the best way to make a nested form in Django 2?

Good day to all. I'm doing my first Django project and I'm stuck on a seemingly simple thing: there is an order form. Each order belongs to one or more categories. I made the functionality of creating orders and categories. And now I want to make it so that in the order creation form you can call the form for creating a new category on the fly and create it, if necessary. Actually, such a scheme is implemented in the admin panel of my project (when you click on the plus sign, a form for creating a category appears):5ca5bb6aed467412543323.png
How can I replicate this behavior in my form? I dug in the direction of Inline formsets, however, both in the documentation and in the open spaces of Google, I have not yet found an answer on how exactly to implement this behavior. In addition, as I understand with the Many to Many relationship, this method will not work. I also tried as suggested in this article: , but this also did not lead to the desired result. I had to return to the starting point, where the creation of an order and a category are processed in different views.
Here are the code snippets:

# 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-методы, не относящиеся к вопросу

I would be very grateful for any help (advice on the curvature of the code or its design is also welcome)

Answer the question

In order to leave comments, you need to log in

1 answer(s)
7
776166, 2019-04-04
@776166

Well, it's like they're different things.
If you need a new category in the process of creating an object, then you first add it, then update the form of the object and move on.
Technically, this can be done in different ways. For example, after creating a category, reset the field with categories. Or reload the entire form, but there are some nuances.
As a crutch, you can add fields with new categories directly to the object creation form and process it when submitting. But I wouldn't do that.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question