{"id":8951,"library":"django-ical","title":"Django iCal","description":"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.","status":"active","version":"1.9.2","language":"en","source_language":"en","source_url":"https://github.com/jazzband/django-ical","tags":["django","ical","calendar","feed","syndication","ics","events"],"install":[{"cmd":"pip install django-ical","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Core web framework integration; requires Django >= 1.3.","package":"Django","optional":false},{"reason":"Used under the hood to generate iCalendar data.","package":"icalendar","optional":false}],"imports":[{"note":"This is the primary class for defining iCalendar feeds, inheriting from Django's `Feed`.","symbol":"ICalFeed","correct":"from django_ical.views import ICalFeed"}],"quickstart":{"code":"from django.db import models\nfrom django.urls import path\nfrom django_ical.views import ICalFeed\n\n# models.py (example in an app like 'myapp')\nclass Event(models.Model):\n    title = models.CharField(max_length=200)\n    description = models.TextField()\n    start_datetime = models.DateTimeField()\n    end_datetime = models.DateTimeField(null=True, blank=True)\n    created_at = models.DateTimeField(auto_now_add=True)\n\n    def __str__(self):\n        return self.title\n\n# feeds.py (example in 'myapp/feeds.py')\nclass EventFeed(ICalFeed):\n    product_id = '-//example.com//Example Calendar//EN'\n    timezone = 'UTC'\n    file_name = 'events.ics'\n\n    def title(self, obj):\n        return 'My Example Calendar'\n\n    def description(self, obj):\n        return 'A calendar feed for all events.'\n\n    def items(self):\n        return Event.objects.all().order_by('-start_datetime')\n\n    def item_title(self, item):\n        return item.title\n\n    def item_description(self, item):\n        return item.description\n\n    def item_start_datetime(self, item):\n        return item.start_datetime\n\n    def item_end_datetime(self, item):\n        return item.end_datetime\n    \n    def item_guid(self, item):\n        return f\"event-{item.id}@example.com\"\n\n# urls.py (example in your project's urls.py)\n# from myapp.feeds import EventFeed\n\n# urlpatterns = [\n#     # ... other urls\n#     path('calendar/events.ics', EventFeed()),\n# ]","lang":"python","description":"To create an iCal feed, define a model for your events, then create a subclass of `ICalFeed`. This class should implement methods like `items()`, `item_title()`, `item_description()`, `item_start_datetime()`, and critically, `item_guid()` for unique event identification. Finally, wire it into your `urls.py`."},"warnings":[{"fix":"Ensure `item_guid(self, item)` returns a truly unique string for each event, often by combining a unique database ID with a domain name, e.g., `f\"event-{item.id}@yourdomain.com\"`.","message":"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.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Set the `file_name` attribute on your `ICalFeed` subclass (e.g., `file_name = 'events.ics'`). This can also be a method for dynamic filenames.","message":"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.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Do not rely on `item_link` for iCal feeds. The iCalendar standard uses `URL` for event links, which is not directly exposed as `item_link` but can be manually added as an extra property if needed via `item_extra_properties`.","message":"Unlike Django's standard syndication feeds, `django-ical` ignores the `item_link` property.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Optimize your `items()` method using `select_related()` or `prefetch_related()` for related data. Avoid complex lookups in `item_*` methods if possible, or ensure data is pre-fetched.","message":"Retrieving many related objects within `items()` or `item_*` methods can lead to 'N+1' query problems, severely degrading performance for large calendars.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Ensure you have run `pip install django-ical` and added `'django_ical'` to your `INSTALLED_APPS` list in `settings.py`.","cause":"The `django_ical` application is not included in your Django project's `INSTALLED_APPS` setting, or the package was not installed.","error":"ModuleNotFoundError: No module named 'django_ical'"},{"fix":"Implement 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\"`.","cause":"The `item_guid` method in your `ICalFeed` subclass is either missing or does not generate a unique identifier for each event.","error":"Calendar client (e.g., Google Calendar, Apple Calendar) only shows the latest event or fails to update/add new events from the feed."},{"fix":"Ensure 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.","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.","error":"The downloaded .ics file appears corrupted or invalid according to a calendar validator, possibly due to incorrect newline formatting (e.g., 'invalid newline format')."}]}