Reputation: 55
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
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
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
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
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
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 thatunicode(p)
will return a Unicode string, andstr(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