Django iCal
django-ical is a simple library/framework for creating iCal feeds based on Django's syndication feed framework. It extends Django's built-in feed system to support iCalendar-specific properties and uses the `icalendar` library for generation. The current version is 1.9.2, and it is actively maintained by Jazzband.
Common errors
-
ModuleNotFoundError: No module named 'django_ical'
cause The `django_ical` application is not included in your Django project's `INSTALLED_APPS` setting, or the package was not installed.fixEnsure you have run `pip install django-ical` and added `'django_ical'` to your `INSTALLED_APPS` list in `settings.py`. -
Calendar client (e.g., Google Calendar, Apple Calendar) only shows the latest event or fails to update/add new events from the feed.
cause The `item_guid` method in your `ICalFeed` subclass is either missing or does not generate a unique identifier for each event.fixImplement or review your `item_guid(self, item)` method to return a string that is universally unique for each distinct event, typically by embedding the event's primary key and your domain, e.g., `return f"event-{item.id}@yourdomain.com"`. -
The downloaded .ics file appears corrupted or invalid according to a calendar validator, possibly due to incorrect newline formatting (e.g., 'invalid newline format').
cause While `django-ical` generally handles newlines correctly through `icalendar`, if you're attempting custom `HttpResponse` manipulation, newline characters might be rendered incorrectly for the iCal standard.fixEnsure that `HttpResponse` objects intended to serve `.ics` files have the correct `Content-Type` header (`'text/calendar'`) and that any manually generated iCalendar content uses `\r\n` for newlines as required by RFC 2445. `django-ical`'s `ICalFeed` handles this automatically.
Warnings
- gotcha Events may not appear or update correctly in calendar clients if `item_guid()` does not return a globally unique identifier for each event. Many clients rely on this for proper syncing and deduplication.
- gotcha By default, `django-ical` does not set the `Content-Disposition` HTTP header, which means downloaded `.ics` files might not have a suggested filename in browsers.
- gotcha Unlike Django's standard syndication feeds, `django-ical` ignores the `item_link` property.
- gotcha Retrieving many related objects within `items()` or `item_*` methods can lead to 'N+1' query problems, severely degrading performance for large calendars.
Install
-
pip install django-ical
Imports
- ICalFeed
from django_ical.views import ICalFeed
Quickstart
from django.db import models
from django.urls import path
from django_ical.views import ICalFeed
# models.py (example in an app like 'myapp')
class Event(models.Model):
title = models.CharField(max_length=200)
description = models.TextField()
start_datetime = models.DateTimeField()
end_datetime = models.DateTimeField(null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
# feeds.py (example in 'myapp/feeds.py')
class EventFeed(ICalFeed):
product_id = '-//example.com//Example Calendar//EN'
timezone = 'UTC'
file_name = 'events.ics'
def title(self, obj):
return 'My Example Calendar'
def description(self, obj):
return 'A calendar feed for all events.'
def items(self):
return Event.objects.all().order_by('-start_datetime')
def item_title(self, item):
return item.title
def item_description(self, item):
return item.description
def item_start_datetime(self, item):
return item.start_datetime
def item_end_datetime(self, item):
return item.end_datetime
def item_guid(self, item):
return f"event-{item.id}@example.com"
# urls.py (example in your project's urls.py)
# from myapp.feeds import EventFeed
# urlpatterns = [
# # ... other urls
# path('calendar/events.ics', EventFeed()),
# ]