Django Recurrence

1.14 · active · verified Thu Apr 16

django-recurrence is a utility for working with recurring dates in Django. It provides `Recurrence/Rule` objects based on a subset of rfc2445 (wrapping `dateutil.rrule`), a `RecurrenceField` for database storage, and a JavaScript widget for user input. The library is currently at version 1.14 and is actively maintained by the Jazzband community, with regular releases to support new Django and Python versions.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to define a model with `RecurrenceField`, populate it with a basic weekly recurrence rule, and then retrieve occurrences within a date range. It also highlights the importance of setting `dtstart` when querying for occurrences across a range, especially for past events.

import os
from django.conf import settings
from django.db import models

# Minimal Django setup for demonstration
if not settings.configured:
    settings.configure(
        INSTALLED_APPS=[
            'django.contrib.auth',
            'django.contrib.contenttypes',
            'recurrence' # Add 'recurrence' to INSTALLED_APPS
        ],
        DATABASES={'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:'}},
        SECRET_KEY=os.environ.get('DJANGO_SECRET_KEY', 'a-very-secret-key-for-testing'),
        USE_TZ=True # Recommended for date/time handling
    )

import django
django.setup()

from recurrence.fields import RecurrenceField
from datetime import date, datetime

class Event(models.Model):
    title = models.CharField(max_length=200)
    start_date = models.DateField(default=date.today)
    recurrences = RecurrenceField()

    class Meta:
        app_label = 'myapp' # Required for minimal Django setup

    def __str__(self):
        return self.title

# Create an event (example for admin/programmatic creation)
# In a real app, this would be handled via forms/admin
weekly_event = Event.objects.create(
    title="Weekly Meeting",
    recurrences=RecurrenceField().compress_rules([
        "RRULE:FREQ=WEEKLY;BYDAY=MO,WE,FR;COUNT=10",
        "RDATE:20260420T090000", # Explicit date/time for specific occurrence
        "EXDATE:20260501T090000" # Exclude a specific date
    ])
)

# Retrieve occurrences for the event
# Note: RecurrenceField itself deals with recurrences, not specific time info from start_date/time.
# When using .between(), it's crucial to set dtstart for past occurrences.
start_range = datetime(2026, 4, 1, 0, 0, 0)
end_range = datetime(2026, 6, 30, 23, 59, 59)

print(f"Occurrences for '{weekly_event.title}' between {start_range.date()} and {end_range.date()}:")
for occ_date in weekly_event.recurrences.between(start_range, end_range, dtstart=start_range, inc=True):
    print(f"- {occ_date.date()}")

# Example of getting the next occurrence
next_occurrence = weekly_event.recurrences.after(datetime.now())
if next_occurrence:
    print(f"\nThe next occurrence after now is: {next_occurrence.date()}")

view raw JSON →