Registry / web-framework / django-recurrence

django-recurrence

JSON →
library1.14pypypi✓ verified 86d ago

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.

pip install django-recurrence
INSTALL
IMPORT
SIG · DJANGO-RECURRENCE
D
django-recurrence
web-frameworkpythonv1.14
Install
3.6s avg
Import
814ms
Disk
67MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v1.14 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.920 runs
installs and imports cleanly · install 0.0s · import 0.863s · 67.9MB
glibc
py 3.103.920 runs
installs and imports cleanly · install 3.6s · import 0.766s · 68MB
67MB installed
● package 67MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

RecurrenceField
from recurrence.fields import RecurrenceField
Recurrence
from recurrence.forms import Recurrence
Used in forms for creating recurrence objects programmatically, distinct from the field itself.

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()}")
Debug
Known issues
breakingVersion 1.13 dropped support for Python <= 3.9 and Django <= 4.2.
fix
Ensure your project uses Python 3.9+ and Django 4.2+ (preferably 5.2+ for the latest support) before upgrading to django-recurrence 1.13 or newer.
affects: 1.13 and higher
breakingVersion 1.12 dropped support for Django < 4 and Python < 3.9.
fix
Upgrade your Django project to version 4.0 or newer and Python to 3.9 or newer before installing or upgrading to django-recurrence 1.12 or newer.
affects: 1.12 and higher
gotchaWhen querying recurrence occurrences using methods like `between()`, `before()`, or `after()`, omitting the `dtstart` parameter can lead to unexpected results, as it may implicitly default to the current time, thus ignoring occurrences before `datetime.now()`.
fix
Always explicitly provide the `dtstart` parameter (e.g., `dtstart=datetime(year, month, day)`) to specify the desired start of the recurrence pattern for accurate results across the full range you intend to query. Set `inc=True` if you want to include the `dtstart` or `dtend` date in the results if it's an occurrence.
affects: All versions
gotchaThe `RecurrenceField` primarily defines the *pattern* of recurrence and does not inherently manage specific time information (e.g., `start_time`) or timezone awareness for individual occurrences. It wraps `dateutil.rrule`, which generates `datetime` objects. Combining it with naive Django `TimeField`s can lead to timezone-related issues.
fix
If your application requires precise time and timezone handling for recurring events, ensure your Django project is configured for timezone support (`USE_TZ = True`), and consider storing event start/end times in a `DateTimeField` rather than a `TimeField` for better integration and timezone awareness, managing the `datetime` objects returned by recurrence. Explicitly set `tzinfo` when creating `datetime` objects for recurrence calculations.
affects: All versions
Errors
Common errors & fixes
RecurrenceField is not rendered correctly in Django admin or forms (missing JavaScript widget).
The necessary JavaScript and CSS static files, along with the `javascript_catalog` URL, are not correctly included in your project or templates.
fix
1. Add `'recurrence'` to your `INSTALLED_APPS`. 2. Ensure `django.contrib.staticfiles` is also in `INSTALLED_APPS` and run `python manage.py collectstatic`. 3. In your `urls.py`, include the `javascript_catalog` view: `from django.urls import re_path as url; from django.views.i18n import JavaScriptCatalog; js_info_dict = {'packages': ('recurrence', )}; urlpatterns += [url(r'^jsi18n/$', JavaScriptCatalog.as_view(), js_info_dict), ]`. 4. In your template, include `{{ form.media }}` within the `<head>` section.
ImportError: No module named 'recurrence.fields'
The `django-recurrence` library is not installed, or `recurrence` is not added to `INSTALLED_APPS`.
fix
First, install the package: `pip install django-recurrence`. Then, ensure `'recurrence'` is included in your `INSTALLED_APPS` tuple in your Django project's `settings.py` file.
I can create recurring events, but how do I delete or edit a *single* occurrence without affecting the whole series?
The library works by defining rules, and modifying a single occurrence requires adding an explicit exception to that rule, rather than directly editing an 'instance'.
fix
To delete a single occurrence, you must add an `EXDATE` (Exclusion Date) property to the recurrence rule for that specific date. To edit a single occurrence (e.g., change its time or title), you typically treat it as an `EXDATE` and create a new, separate single-day event (or `RDATE`) for the modified occurrence, while leaving the main recurrence rule untouched.
Upgrade
Version history
1.14latest on PyPI · released Dec 19, 2025
Audit
Dependencies
DjangorequiredCore framework integration as a model field and form widget.
python-dateutilrequiredProvides the underlying recurrence rule logic (rrule) which django-recurrence wraps.
Agent activity
8 hits · last 30 days
node
8
Resources
django-recurrence — pip install django-recurrence · libregistry