Emmett Dudley Emmett Dudley - 1 year ago 62
Python Question

Assigning the correct ID to a form?

So I'm expanding on the official tutorial, and I'm trying to let a user create their own poll. I'm having trouble assigning the correct question_id to the choice, so the choice aligns in the database with the question and both can be read off. Here is my view:

def poll_create(request):
if request.method == "POST":
Qform = QuestionForm(request.POST)
Cform = ChoiceForm(request.POST)
if Qform.is_valid():
poll = Qform.save(commit=False)
poll.author = request.user
poll.pub_date = timezone.now()
if Cform.is_valid():
poll = Cform.save(commit=False)
poll.author = request.user
findid = Question.objects.all().order_by("-id")[0] ##Finds the id of the last question in database
poll.question_id = findid.id + 1
return redirect('polls:detail', pk=poll.pk)
Qform = QuestionForm()
Cform = ChoiceForm()
return render(request, 'polls/create.html', {'Qform': Qform, 'Cform': Cform})

So the idea is to have a question form (Qform) which writes the question to the database, and then below on the webpage a choice form (Cform), which writes the answer to the database. I'm really confused about applying a question_id to the Cform. At the moment, I have this line:

findid = Question.objects.all().order_by("-id")[0] ##Finds the id of the last question in database
poll.question_id = findid.id + 1

Which seems like a very hacky attempt to find the last id and assign it to the next one. It doesnt line up because the poll.pk has a different value. I'm at a loss here and don't really understand what's going on. Any help would be appreciated.

Answer Source

Your code is a bit confusing because you are using the variable poll for questions and choices. It would be better to use question and choice instead.

You should check that both forms are valid before you start saving, otherwise you can end up with a question without a choice if the question form is valid but the choice form is invalid.

After you have saved the question, you can get the id with question.id, and you can assign the question to the choice object. There is no need to do a query to find the latest question id.

Putting that together, you have something like:

if Qform.is_valid() and Cform.is_valid():
    question = Qform.save(commit=False)
    question.author = request.user
    question.pub_date = timezone.now()
    choice = Cform.save(commit=False)
    choice.author = request.user
    choice.question = question
    return redirect('polls:detail', pk=question.pk)

Note also that it's recommended to use lowercase question_form and choice_form, for the form instances, and uppercase QuestionForm and ChoiceForm for the classes.