views:

313

answers:

1

Hello,

In a django app, I have models for a Word (to be learned), a Student (learning it), and StudentWord is a table to handle the many to many relationship:

class Word(models.Model):
    word = models.CharField(max_length=80)
    image = models.ForeignKey(Image)
    language = models.ForeignKey(Language)
    def __unicode__(self):
        return self.word

class Student(models.Model):
    username = models.ForeignKey(User)
    words = models.ManyToManyField(Word, through='StudentWord')
    def __unicode__(self):
        return self.username.username

class StudentWord(models.Model):
    word = models.ForeignKey(Word)
    student = models.ForeignKey(Student)
    level = models.IntegerField()
    nextdate = models.DateField()  <-- this field newly added
    learned = models.BooleanField()
    def __unicode__(self):
        return u'%s %s' % (self.student, self.word)

I had it working, but wanted to add a feature where the app would know when was the next date to ask the student this word. For this, I added the nextdate field to the StudentWord model, deleted the studentword table in MySQL, used syncdb to regenerate it, and used the admin page to successfully add a few studentwords (with the new field for date in it).

However, the following part of the view is generating an error:

def index(request):
    last_question = request.session.get('last_question', 'none')
    student_language = request.session.get('student_language', 'english')
    student=Student.objects.get(username=request.user)
    words_student_knows = Word.objects.filter(studentword__student=student, studentword__learned=True)
    words_student_knows.filter(studentword__nextdate<=datetime.date.today())

The error is:

Exception Type:   NameError
Exception Value:  
global name 'studentword__nextdate' is not defined
Exception Location:  /home/wordcode/words/vocabulary/views.py in index, line 32

Line 32 is the last line of the snippet from the view above. When I remove that filter, the error goes away, so it seems to be related to the new field. I used: import datetime ...in the view, and I am able to use datetime.date.today() elsewhere in the code without a problem.

My guess was that somehow it hasn't picked up on the newly added field, but since the admin site understands that it's there, that doesn't seem to likely, and in any event deleting the studentword table and recreating it ought to do the trick.

Any help or advice is appreciated.

+1  A: 

You've misunderstood how you pass comparisons in Django model filters. Instead of your last line, you need to do this:

words_student_knows.filter(studentword__nextdate__lte=datetime.date.today())

Spelled this way, the filter is correctly passed to the model manager as a keyword argument, which is then broken down into its constituent parts and processed successfully within the manager.

The way you had it, though, meant that Python was trying to evaluate the result of studentword__nextdate<=datetime.date.today() right there in the calling function, aiming to pass a Boolean value to the destination function. Of course, there's no local variable called studentword__nextdate, hence the error.

Daniel Roseman
Right you are, thanks!
rossdavidh