Stanislav Shostak
Stanislav Shostak

Reputation: 3

Django custom manager dont work

Based on this question i wrote this code:

class CourseManager(models.Manager):
    def current(self):
        return self.filter(date_start < datetime.datetime.now()).filter(date_end > datetime.datetime.now())

class PlannedCourse(models.Model):
    course = models.ForeignKey(ECourse)
    date_start = models.DateTimeField()
    date_end = models.DateTimeField(blank=True)
    ...
    objects = CourseManager()
    def __str__(self):
        return self.course.name + ' ' + self.date_start.strftime("%d-%m-%Y %H:%M") + ' - ' + self.date_end.strftime("%d-%m-%Y %H:%M")

but when I try to run PlannedCourse.objects.current() I get the error:

NameError: name 'date_start' is not defined.

I'm a newbie and don't understand why this happens :(

Upvotes: 0

Views: 94

Answers (2)

knbk
knbk

Reputation: 53669

You're comparing an undefined python object (date_start) with a date in python. However, the goal of a queryset is to compare objects in the database. Even if date_start was defined, this would be the equivalent of calling .filter(True) or .filter(False).

To tell Django to check in the database, you have to pass keyword arguments to the filter that are converted to a query by the ORM:

return self.filter(date_start__lt=datetime.datetime.now(),
                   date_end__gt=datetime.datetime.now())

Note that you're not actually comparing date_start and datetime.datetime.now(), the .filter function uses **kwargs, and gets the following arguments as a dictionary:

{
    'date_start__lt': datetime.datetime.now(),
    'date_end__gt': datetime.datetime.now(),
}

The __lt and __gt are field lookups that tell the queryset how to perform the comparison in the database.

Upvotes: 1

catavaran
catavaran

Reputation: 45575

You should use fields lookups: __gt instead of > and __lt instead of <:

class CourseManager(models.Manager):
    def current(self):
        return self.filter(date_start__lt=datetime.datetime.now(),
                           date_end__gt=datetime.datetime.now())

Upvotes: 5

Related Questions