Anushrut Gupta
Anushrut Gupta

Reputation: 55

Django Polls App: AttributeError: 'Choice' object has no attribute 'question_text'

I was doing the tutorial on the Django website, when I got this error. I am using OS X 10.10.

>>> q.choice_set.create(choice_text='Not much', votes=0)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/Library/Python/2.7/site-packages/Django-1.7.8-py2.7.egg/django/db/models/base.py", line 458, in __repr__
    u = six.text_type(self)
  File "/Users/anushrutgupta/Documents/IMG/Django/mysite/polls/models.py", line 22, in __str__
    return self.choice_text
AttributeError: 'Choice' object has no attribute 'question_text'
>>> 

My models.py:

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)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

    def __str__(self):   
        return self.choice_text

Is something wrong in the models?

Upvotes: 4

Views: 7269

Answers (5)

Isha Gupta
Isha Gupta

Reputation: 13

So, the two tables are linked together using the foreign key "question"

For the table "Question" to relate to the table "Choices", you need to add a parameter called "related_name" in the ForeignKeyField

Like that, for the questions to be mapped with 1 or n choices, you can use the related name

The code would look like this:

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

Upvotes: 1

deepakkumar
deepakkumar

Reputation: 147

I found the solution to this problem, I was also committing the same mistake when you are defining the variable q,

q = Question.objects.get(pk=1) #it should be like this
q.choice_set.all() #this will show an empty list (only if it's empty)
q.choice_set.create(choice_text="sheela ki jawani", votes=0) #and so on

I was doing the first step of defining q wrongly instead of .get (pk=1), I was using

q = Question.objects.all() #this is wrong

Upvotes: 1

Saif Ali
Saif Ali

Reputation: 39

So while defining q, please use .get() if you weren't already.
You can read on the difference between .filter() and .get() in official documentation.
As far as I can recall, .filter() doesn't hold the object for you to manipulate it using its attributes.

Upvotes: 2

Luke
Luke

Reputation: 11

I'm doing the same exercise and based on your code I managed to make mine work. (show Question: What's up?). I must say I find the step-by-step instructions in the tutorial pretty confusing.

My code has two extra lines:

 from __future__ import unicode_literals # future between underscores, 2 on each side

and

from django.utils.encoding import python_2_unicode_compatible

Upvotes: 1

TaipanRex
TaipanRex

Reputation: 820

Looks like a typo in your code on line 22 of models.py, you have return self.question_text but it should be return self.choice_text.

EDIT: I see you are using Python 2.7, with Python 2 you need to use __unicode__ and not __str__.

__str__ or __unicode__?

On Python 3, it’s easy, just use __str__().

On Python 2, you should define __unicode__() methods returning unicode values instead. Django models have a default __str__() method that calls __unicode__() and converts the result to a UTF-8 bytestring. This means that unicode(p) will return a Unicode string, and str(p) will return a bytestring, with characters encoded as UTF-8. Python does the opposite: object has a __unicode__ method that calls __str__ and interprets the result as an ASCII bytestring. This difference can create confusion.

If all of this is gibberish to you, just use Python 3.

Upvotes: 5

Related Questions