@ermolushka

Как правильно работать с вложенными формами в Django?

Всем привет. У меня есть три модели, хочется при создании Receipt также создавать Ingredient и CookingStep. Читал про inline formsets, но пока не понял, как с этим работать на уровне views и 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 %}


Буду благодарен за подробную помощь.
  • Вопрос задан
  • 1004 просмотра
Решения вопроса 1
sergey-gornostaev
@sergey-gornostaev Куратор тега Django
Седой и строгий
Документация очень подробна на этот счёт.

forms.py
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'))

views.py
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})

receipt_edit.html
<form method="post" action="">
    <table>
        {{ formset }}
    </table>
</form>
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы