django-oscar-freeletter
Wires django-freeletter into django-oscar: registers a "product" issue-block type (and a "blog post" one, if django-oscar-blog is also installed), plus an Oscar dashboard section for managing issues and subscribers.
What this package does, and doesn't, do
- Registers freeletter's
"product"block type — an issue can feature a catalogue product, resolved via Oscar's ownProductmodel, with no new lookup endpoint (it reuses Oscar's existing dashboard product autocomplete,dashboard:catalogue-product-lookup). - Registers a
"blog_post"block type only ifoscar_blogis installed (checked at runtime viaapps.is_installed, not imported unconditionally) — an issue can feature adjango-oscar-blogpost. - An Oscar dashboard section (
oscar_freeletter.dashboard) under/dashboard/freeletter/: issue list/create/update/delete with an inline block editor (pick "html" free content, a product, or — if installed — a blog post, per block), a one-click "queue for sending" action, and a read-only subscriber list. - It does not ship its own models — everything it manages
(
Issue,IssueBlock,Subscriber) belongs todjango-freeletter; this package only adds Oscar-specific block types and a dashboard UI on top.
Installation
uv add django-oscar-freeletter
# or, with blog-post blocks too (pulls in django-oscar-blog):
uv add "django-oscar-freeletter[blog]"
Plain pip works the same way: pip install django-oscar-freeletter[blog].
Without the blog extra, this package still installs and works fine — it
just registers the "product" block type only.
INSTALLED_APPS = [
...,
"freeletter",
"oscar_blog.apps.OscarBlogConfig", # optional — enables "blog_post" blocks
"oscar_blog.dashboard.apps.BlogDashboardConfig", # optional
"oscar_freeletter.apps.OscarFreeletterConfig",
"oscar_freeletter.dashboard.apps.FreeletterDashboardConfig",
]
Run manage.py migrate (this package ships no migrations of its own —
freeletter's migration is what actually creates the tables).
Wiring the dashboard in
Same fork django-oscar-blog needs (Oscar's DashboardConfig.get_urls()
is a hardcoded list, not auto-discovered) — see this package's own
tests/dashboard.py for a worked example that mounts both
freeletter_dashboard and blog_dashboard in the same fork:
from django.apps import apps
from django.urls import include, path
from oscar.apps.dashboard.apps import DashboardConfig as OscarDashboardConfig
class DashboardConfig(OscarDashboardConfig):
def ready(self):
super().ready()
self.freeletter_app = apps.get_app_config("freeletter_dashboard")
def get_urls(self):
urls = super().get_urls()
urls.append(path("freeletter/", include(self.freeletter_app.urls[0])))
return urls
Then add a nav entry (e.g. under Content, alongside blog posts) via
OSCAR_DASHBOARD_NAVIGATION:
{
"label": _("Newsletter issues"),
"url_name": "dashboard:freeletter-issue-list",
},
Translations
The package ships a Spanish translation (src/oscar_freeletter/locale/es/).
Both the .po source and the compiled .mo are committed, so the wheel
includes the .mo and nothing needs compiling on install. After editing a
.po, recompile before releasing:
msgfmt -o src/oscar_freeletter/locale/es/LC_MESSAGES/django.mo \
src/oscar_freeletter/locale/es/LC_MESSAGES/django.po
New strings are extracted with django-admin makemessages -l es run from
src/oscar_freeletter/. A project can override any single string in its own
LOCALE_PATHS without copying the whole catalogue. The newsletter pages and
emails themselves live in django-freeletter, which has its own catalogue.
Development
uv sync
uv run pytest
Requires django-freeletter and (for the "blog_post" tests)
django-oscar-blog — both wired in pyproject.toml's [tool.uv.sources]
as local path dependencies until they're published.
Metadata
Release files for django-oscar-freeletter 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| django_oscar_freeletter-0.3.0.tar.gz | 68.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| django_oscar_freeletter-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 86.3 kB
Release files / django_oscar_freeletter-0.3.0.tar.gz
| Download URL | django_oscar_freeletter-0.3.0.tar.gz |
|---|---|
| Size | 68.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
626b518409aaf7f7b6bc49e077b5a9dd9731e6a5b141b6037fbc9baf00999a2b
|
|
BLAKE2b-256 checksum How to use checksums |
e6dee12bce4e92d4206f04242296cfd0daa0505ee5f534cd0996f1a8d85d4203
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.9 {"installer":{"name":"uv","version":"0.12.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / django_oscar_freeletter-0.3.0-py3-none-any.whl
| Download URL | django_oscar_freeletter-0.3.0-py3-none-any.whl |
|---|---|
| Size | 17.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d3e5c1f9953a09f731dfd4c810f304cd67fcadac9f063918fb4d809020eaa7d5
|
|
BLAKE2b-256 checksum How to use checksums |
d1bd7e2b5f18c2347e44bd7899d922fd493b9ee4dad864cbbb6958f652fd3037
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.9 {"installer":{"name":"uv","version":"0.12.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|