Login

ActiveManager: filter objects depending on publication and/or expiration dates

Author:
haplo
Posted:
July 1, 2008
Language:
Python
Version:
.96
Score:
3 (after 3 ratings)

This manager is intended for use with models with publication and/or expiration dates. Objects will be retrieved only if their publication and/or expiration dates are within the current date.

Use is very simple:

class ExampleModel(models.Model):
    publish_date = models.DateTimeField()
    expire_date = models.DateTimeField(blank=True, null=True)

    objects = models.Manager()
    actives = ActiveManager(from_date='publish_date', to_date='expire_date')

ExampleModel.actives.all() # retrieve active objects according to the current date

The manager works correctly with nullable date fields. A null publication date means "always published (until expiration date)" and a null expiration date means "never expires".

Most models should define the objects manager as the default manager, because otherwise out of date objects won't appear in the admin app.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
from datetime import datetime

from django.db import models

class ActiveManager(models.Manager):
    """
    This special manager only retrieves active objects (when the current date
    is between the object's publish date and/or its expiration date).

    The date fields are given when creating the Manager instance. If either is
    None then the manager will not take it into account for filtering.

    Example definition for a model:

    class ExampleModel(models.Model):
        publish_date = models.DateTimeField()
        expire_date = models.DateTimeField(blank=True, null=True)

        actives = ActiveManager(from_date='publish_date', to_date='expire_date')

    Or if the model only had an expire_date:

    class ExampleModel(models.Model):
        expire_date = models.DateTimeField(blank=True, null=True)

        actives = ActiveManager(from_date=None, to_date='expire_date')

    Each instance of the manager has an attribute date_filters which can be used in
    custom queries. For example, if you have a ManyToMany relationship to a model
    with ActiveManager and you can't access via the manager (because you
    need to use select_related, for example) then you can do:

    instance.many_to_many.filter(*ExampleModel.actives.date_filters)

    """

    def __init__(self, from_date=None, to_date=None):
        super(ActiveManager, self).__init__()
        self.from_date = from_date
        self.to_date = to_date
        now = datetime.now
        if from_date and to_date:
            self.date_filters = (models.Q(**{'%s__isnull' % self.to_date: True}) |
                                 models.Q(**{'%s__gte' % self.to_date: now}),
                                 models.Q(**{'%s__isnull' % self.from_date: True}) |
                                 models.Q(**{'%s__lte' % self.from_date: now}))

        elif from_date:
            self.date_filters = (models.Q(**{'%s__isnull' % self.from_date: True}) |
                                 models.Q(**{'%s__lte' % self.from_date: now}),)
        elif to_date:
            self.date_filters = (models.Q(**{'%s__isnull' % self.to_date: True}) |
                                 models.Q(**{'%s__gte' % self.to_date: now}),)
        else:
            raise ValueError, "At least one date field is required"

    def get_query_set(self):
        """Retrieves items with publication dates according to self.date_filters
        """
        return super(ActiveManager, self).get_query_set().filter(*self.date_filters)

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 11 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 6 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 7 months ago
  5. Help text hyperlinks by sa2812 1 year, 8 months ago

Comments

josephmuli (on June 6, 2016):

Hi, thanks for the snippet, really helpful but what if the object is expired? how does one retrieve?

#

Please login first before commenting.