Is there a possibility to pass fields from different models to CreateView in Django?

I’m extending polls app from official Django tutorial and want to pass Question field question_text along with Choice field choice_text to CreateView generic View, to let the user create a Question along with it’s choices at the same time. Unfortunately I can only pass Question model with question_text to the CreateView

I know CreateView takes only one model so is there a possibility to maybe overwrite it somehow? Question is a foreignKey in a database to the Choice model.

I found some answers using extra_views but i do not want to use some external source to do that

Below my code

Views

class CreateView(LoginRequiredMixin, generic.CreateView):
   success_url = reverse_lazy('polls:index')
   redirect_field_name = 'accounts:signup'
   model = Question
   fields = ['question_text']
   template_name = 'polls/poll_form.html'

   def form_valid(self, form):
       form.instance.author = self.request.user
       response = super(CreateView, self).form_valid(form)
       return response

Models

class Question(models.Model):
   question_text = models.CharField(max_length=200)
   author = models.ForeignKey(User, default='Default', on_delete=models.CASCADE)
   pub_date = models.DateTimeField('date published', default=timezone.now)


   def __str__(self):
       return self.question_text

   def was_published_recently(self):
       return self.pub_date >= timezone.now() - datetime.timedelta(days=1)

class Choice(models.Model):
   question = models.ForeignKey(Question, on_delete=models.CASCADE)
   choice_text = models.CharField(max_length=200)
   votes = models.IntegerField(default=0)

   def __str__(self):
       return self.choice_text

Urls

app_name = 'polls'
urlpatterns = [
   path('', views.IndexView.as_view(), name='index'),
   path('new/', views.CreateView.as_view(), name='create'),
   path('<int:pk>/', views.DetailView.as_view(), name='detail'),
   path('<int:pk>/results/', views.ResultsView.as_view(), name='results'),
   path('<int:question_id>/vote/', views.vote, name='vote'),]

Without including an external library, I don’t think you’re going to find the standard Django CRUD CBVs to be the best / easiest solution.

When I’ve had to do this, I build from FormView as my base. I build my form from my base class and use an inline formset to handle the related classes, with a little bit of JavaScript to make that formset dynamic.

1 Like

I thought that it’s quite obvious and is included as a standard in Django but the explanation and links you’ve provided make it easy to follow enough anyway, even with external library! Thank you very much Mr., I’ll definitely try that