Combinando dos formas en una vista Django

Estoy trabajando para agregar más funcionalidad a la aplicación de encuestas que se realiza en el tutorial oficial de Django. Una de las cosas en las que estoy trabajando es hacer que las encuestas / opciones sean creables por los usuarios registrados (en lugar de hacerlo en una pantalla de administración, donde el tutorial nos deja).

Estoy buscando crear una vista donde un usuario pueda crear una Encuesta, y luego incluir algunas opciones para asociar a la Encuesta. El administrador de Django lo hace automáticamente, y no estoy seguro de cómo escribir esto en una vista.

Para empezar, estos son mis archivos relevantes:

modelos.py

import datetime from django.db import models from django.utils import timezone class Poll(models.Model): question_text = models.CharField(max_length=200) pub_date = models.DateTimeField('date published') def __unicode__(self): return self.question_text def was_published_recently(self): return self.pub_date >= timezone.now() - datetime.timedelta(days=1) was_published_recently.admin_order_field = 'pub_date' was_published_recently.boolean = True was_published_recently.short_description = 'Published recently?' class Choice(models.Model): question = models.ForeignKey(Poll) choice_text = models.CharField(max_length=200) votes = models.IntegerField(default=0) def __unicode__(self): return self.choice_text 

forms.py

 from django import forms from .models import Poll, Choice from datetime import datetime class PollForm(forms.ModelForm): question_text = forms.CharField(max_length=200, help_text="Please enter the question.") pub_date = forms.DateTimeField(widget=forms.HiddenInput(), initial = datetime.now()) class Meta: model = Poll fields = ("__all__") class ChoiceForm(forms.ModelForm): choice_text = forms.CharField(max_length=200, help_text="Please enter choices.") votes = forms.IntegerField(widget=forms.HiddenInput(),initial=0) exclude = ('poll',) 

vistas.py

 def add_poll(request): # A HTTP POST? if request.method == 'POST': form = PollForm(request.POST) # Have we been provided with a valid form? if form.is_valid(): # Save the new category to the database. form.save(commit=True) # Now call the index() view. # The user will be shown the homepage. return render(request, 'polls/index.html', {}) else: # The supplied form contained errors - just print them to the terminal. print form.errors else: # If the request was not a POST, display the form to enter details. form = PollForm() # Bad form (or form details), no form supplied... # Render the form with error messages (if any). return render(request, 'polls/add_poll.html', {'form': form}) 

Actualmente, mi vista me permite a un usuario agregar una encuesta. Simplemente no estoy seguro de cómo adaptarlo para pasar el texto ingresado como question_text del modelo Poll, al modelo Choice y, a su vez, a ChoiceForm.

Cualquier orientación y recomendaciones son siempre apreciadas!

Saludos paul

Formsets son la forma de hacerlo en django.

Primero agregue default valor default para el campo Poll.pub_date :

 class Poll(models.Model): question_text = models.CharField(max_length=200) pub_date = models.DateTimeField('date published', default=timezone.now) 

Entonces haz las formas un poco más simples:

 class PollForm(forms.ModelForm): class Meta: model = Poll fields = ('question_text', ) class ChoiceForm(forms.ModelForm): class Meta: model = Choice fields = ('choice_text',) 

Agregue soporte de formset a su vista:

 from django.forms.formsets import formset_factory def add_poll(request): ChoiceFormSet = formset_factory(ChoiceForm, extra=3, min_num=2, validate_min=True) if request.method == 'POST': form = PollForm(request.POST) formset = ChoiceFormSet(request.POST) if all([form.is_valid(), formset.is_valid()]): poll = form.save() for inline_form in formset: if inline_form.cleaned_data: choice = inline_form.save(commit=False) choice.question = poll choice.save() return render(request, 'polls/index.html', {}) else: form = PollForm() formset = ChoiceFormSet() return render(request, 'polls/add_poll.html', {'form': form, 'formset': formset}) 

Y finalmente tu plantilla:

 
{% csrf_token %} {{ form }} {{ formset }}