V
V
V2016-08-31 18:55:54
Django
V, 2016-08-31 18:55:54

How to work with nested forms in Django?

Hello. I have three models, I want to also create Ingredient and CookingStep when creating Receipt. I read about inline formsets, but have not yet figured out how to work with it at the level of views and templates.
#models.py

from django.db import models

class Receipt(models.Model):
  name = models.CharField(max_length=255)
  description = models.TextField(max_length=1024)
  hour = models.IntegerField(default=0)
  minute = models.IntegerField(default=1)
  multivarka = models.BooleanField(default=False)

  def __str__(self):
    return "%s" % (self.name)

class Ingredient(models.Model):
  name = models.CharField(max_length=255)
  count = models.IntegerField(default=0) #200gr, 1kg etc
  value = models.CharField(max_length=255) #gramm, kg etc
  receipts = models.ForeignKey(Receipt)

  def __str__(self):
    return "%s" % (self.name)

class CookingStep(models.Model):
  description = models.TextField(max_length=1024)
  receipts = models.ForeignKey(Receipt)

  def __str__(self):
    return "%s" % (self.description)

#forms.py
from django import forms
from .models import Receipt, Ingredient, CookingStep

class ReceiptForm(forms.ModelForm):

  class Meta:
    model = Receipt
    fields = ('name', 'description', 'hour', 'minute', 'multivarka',)

#views.py
from django.shortcuts import HttpResponse, render, get_object_or_404, redirect
from .models import Receipt
from .forms import ReceiptForm

def receipt_index(request):
    latest_receipt_list = Receipt.objects.order_by('name')
    context = {'latest_receipt_list': latest_receipt_list}
    return render(request, 'admin_site/receipt_index.html', context)

def receipt_detail(request, receipt_id):
    receipt = get_object_or_404(Receipt, pk=receipt_id)
    return render(request, 'admin_site/receipt_detail.html', {'receipt': receipt})

def receipt_new(request):
    if request.method == "POST":
        form = ReceiptForm(request.POST)
        if form.is_valid():
            receipt = form.save(commit=False)
            receipt.save()
            return redirect('/receipts')
    else:
        form = ReceiptForm()
    return render(request, 'admin_site/receipt_edit.html', {'form': form})

#receipt_edit.html
{% block content %}
    <h1>New receipt</h1>
    <form method="POST" class="post-form">{% csrf_token %}
        {{ form.as_p }}
        <button type="submit" class="save btn btn-default">Save</button>
    </form>
{% endblock %}

I would be grateful for detailed help.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
S
Sergey Gornostaev, 2016-09-01
@ermolushka

The documentation is very detailed on this.

from django.forms import ModelForm
from django.forms.models import inlineformset_factory

from models import Receipt, Ingredient

ReceiptFormSet = inlineformset_factory(Receipt, Ingredient, fields=('name', 'count', 'value'))

from forms import ReceiptFormSet

def receipt_new(request):
    if request.method == "POST":
        formset = ReceiptFormSet(request.POST)
        if formset.is_valid():
            formset.save()
            return redirect('/receipts')
    else:
        formset = ReceiptFormSet()
    return render(request, 'admin_site/receipt_edit.html', {'formset': formset})

<form method="post" action="">
    <table>
        {{ formset }}
    </table>
</form>

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question