Clarify "choice_set" in Writing your first Django app, part 2

In part 2 of the great tutorial it should be clarified why and how “choice_set” is available for the Question model.
From the context it was clear for me, but in part 4 I get Pylance errors:

I also found this: python - 'Questions' object has no attribute 'choice_set' - Stack Overflow

Therefore it should be described with 1-2 sentences. Because if you look at the model Question, you don’t see it. From the context and the foreign key in the Choice model, it was clear for me, but others will probably struggle with it.

1 Like

Where would you add these lines and do you have some proposed text that you feel would have helped your understanding? Edit: I ask as a prelude to asking you to open a Trac issue / PR for Django. If it’s not clear, let’s improve it.

1 Like

First, I agree with @CodenameTim here - if you have a specific suggestion, I’m sure it will be welcomed.

However, there is a limit to what should be presented in the tutorial - there’s a lot of the material presented as “do this and don’t worry about ‘why’ yet”.

It is mentioned in the Playing with the api section of the tutorial.

# Give the Question a couple of Choices. The create call constructs a new
# Choice object, does the INSERT statement, adds the choice to the set
# of available choices and returns the new Choice object. Django creates
# a set to hold the "other side" of a ForeignKey relation
# (e.g. a question's choice) which can be accessed via the API.
>>> q = Question.objects.get(pk=1)

# Display any choices from the related object set -- none so far.
>>> q.choice_set.all()
<QuerySet []>

So if a better description is to be provided, this may be the area in which to do it.

That was actually my first thought. Although I didn’t find an edit button or something which directly points to a connected GitHub repository.
But I’ll search for it and add an issue there.

Thank you for pointing that out.
Although I’d assume to read it in the description of https://docs.djangoproject.com/en/4.1/intro/tutorial02/#creating-models last paragraph where ForeignKey is described.

1 Like

I have also been following along the (excellent) tutorial parts carefully. I have hit the same issue mentioned here and in the linked stack overflow question when I reach section 4 of the tutorial. The section with the interactive console had worked fine in section 2 when I was looking for a choice_set from a Question, but now when I get to the changes to the ‘views.py’ file in section 4, it has two errors that seem to be things from the class it can’t recover these are the ‘.choice_set’ in the line:
selected_choice = question.choice_set.get(pk=request.POST[“choice”])
And then the ‘question.id’ in the line:
return HttpResponseRedirect(reverse(“polls:results”, args=(question.id,)))
This seems to be that things that are working in the console from the class definitions relating to the id primary key on the Question and the foreign key from the Choice are not working in there app code itself. Please can you advise and have I perhaps missed an include or something else?

Here is the full content of my models.py file at present:

import datetime
from django.db import models
from django.utils import timezone


class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField("date published")
    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

The full views.py code is as follows:

from django.db.models import F
from django.shortcuts import get_object_or_404, render
from django.http import HttpResponse, HttpResponseRedirect
from django.urls import reverse

from polls.models import Choice, Question

def index(request):
    latest_question_list = Question.objects.order_by("-pub_date")[:5]
    context = {"latest_question_list": latest_question_list}
    return render(request, "polls/index.html", context)


def detail(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(request, "polls/detail.html", {"question": question})


def results(request, question_id):
    response = "You're looking at the results of question %s."
    return HttpResponse(response % question_id)


def vote(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    try:
        selected_choice = question.choice_set.get(pk=request.POST["choice"])
    except (KeyError, Choice.DoesNotExist):
        # Redisplay the question voting form.
        return render(
            request,
            "polls/detail.html",
            {
                "question": question,
                "error_message": "You didn't select a choice.",
            },
        )
    else:
        selected_choice.votes = F("votes") + 1
        selected_choice.save()
        # Always return an HttpResponseRedirect after successfully dealing
        # with POST data. This prevents data from being posted twice if a
        # user hits the Back button.
        return HttpResponseRedirect(reverse("polls:results", args=(question.id,)))

The error messages shown are these two:

Cannot access attribute "choice_set" for class "Question"
  Attribute "choice_set" is unknown [Ln 27, Col 36]
Cannot access attribute "id" for class "Question"
  Attribute "id" is unknown [Ln 44, Col 77]

Thanks.

1 Like

Welcome @IanVaughanRHD !

First, a Side note: When posting code (or templates, error messages, tracebacks, etc), enclose the code between lines of three backtick - ` characters. This means you’ll have a line of ```, then your code, then another line of ```. This forces the forum software to keep your code properly formatted. (I’ve taken the liberty of editing your original post. Please remember to do this in the future.)

Please post the actual error message you are receiving, with the full traceback. (Copy / paste that text into your post as described above.) Also post the complete view that is showing you the error.

Thanks for the speedy and helpful; response, Ken, I’ve edited and included the things asked for above.
I’ve also realised in doing so that the project will still work and the red underlined errors don’t prevent that. Also, I have now added

#.type:.ignore

after those 2 lines in the editor and the errors are no longer highlighted.
Apologies if that is my newcomer error and misunderstanding. I have now proceeded and completed stage 4 of the tutorials and can continue.
thanks.

1 Like