Skip to main content

django-oscar-blog

A blog app for django-oscar: posts, an Oscar dashboard section under Content, and posts that can link out to catalogue products they mention.

What this package does, and doesn't, do

  • A Post model: title/slug/excerpt/body/featured image/author/status (draft/published)/publish date, plus meta_title/meta_description for SEO and a related_products many-to-many onto catalogue.Product.
  • Storefront list/detail views (oscar_blog.urls) and a PostSitemap.
  • An Oscar dashboard section (oscar_blog.dashboard) for staff to create, edit, and delete posts — list/create/update/delete views following the exact same conventions as Oscar's own dashboard.pages app (flatpages), including its permission model (is_staff by default).
  • It does not ship a newsletter integration or a "featured products" CTA anywhere in the storefront — see "Adding a CTA" below. The related-products picker defaults to a plain multi-select but has an opt-in AJAX autocomplete mode — see "Related products" below.

Installation

uv add django-oscar-blog

Add to INSTALLED_APPS, after catalogue/partner (it references catalogue.Product) and after oscar.config.Shop:

INSTALLED_APPS = [
    ...,
    "oscar_blog.apps.OscarBlogConfig",
    "oscar_blog.dashboard.apps.BlogDashboardConfig",
]

Run manage.py migrate — this package ships its own migration.

Wiring the storefront URLs

# urls.py
urlpatterns = [
    path("blog/", include("oscar_blog.urls")),
    ...
]

Templates extend oscar/layout.html under oscar_blog/post_list.html and oscar_blog/post_detail.html — override them the same way you'd override any other Oscar template (a project-level templates/oscar_blog/... directory).

Wiring the dashboard in ("Content" menu)

Oscar's own dashboard.apps.DashboardConfig.get_urls() is a hardcoded list, not auto-discovered — every dashboard section Oscar ships is added there directly, and third-party sections have to fork that config the same way you'd fork any other Oscar app. This package's own test suite (tests/dashboard.py) is a working example of exactly this fork — copy its shape into your project, e.g. a dashboard/apps.py:

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.blog_app = apps.get_app_config("blog_dashboard")

    def get_urls(self):
        urls = super().get_urls()
        urls.append(path("blog/", include(self.blog_app.urls[0])))
        return urls

...and swap "oscar.apps.dashboard.apps.DashboardConfig" for your project's own "yourproject.dashboard.apps.DashboardConfig" in INSTALLED_APPS.

Then add the nav entry under Content, alongside Pages/Email templates/Reviews, by overriding OSCAR_DASHBOARD_NAVIGATION (a plain Django setting — copy Oscar's default from oscar.defaults and insert):

{
    "label": _("Blog posts"),
    "url_name": "dashboard:blog-post-list",
},

into the "Content" entry's "children" list.

Post.related_products is a plain (unordered) ManyToManyField onto catalogue.Product. A published post's detail page lists them under "Mentioned products", linking to each product's own page (post_detail.html). Nothing on the Product side surfaces "posts that mention me" yet — the reverse relation is available as product.blog_posts.all() if a host project wants to add that to a product page.

Dashboard picker widget — two modes, one setting:

OSCAR_BLOG_PRODUCT_AUTOCOMPLETE = True  # default: False
  • Off (default): a plain <select multiple> with every product rendered as an <option>. Fine at a small catalogue's scale; at real scale every dashboard post-edit page load pulls in the whole catalogue.
  • On: the dashboard's related-products field switches to Oscar's own oscar.apps.dashboard.catalogue.widgets.ProductSelectMultiple — a Select2 widget backed by Oscar's already-installed dashboard:catalogue-product-lookup endpoint (oscar.apps.dashboard.catalogue.views.ProductLookupView, a real title__icontains search, already staff-permission-gated). Only the currently selected products are pre-rendered; everything else loads as the user types. No new backend endpoint needed — this project's dashboard/forms.py just wires Oscar's existing one in, plus one real fix Oscar itself doesn't apply consistently: ProductSelectMultiple needs an explicit class="select2 product-select" to actually get AJAX-backed search (confirmed against oscar/static/oscar/js/oscar/dashboard.js's initSelects() — without it, the field would still render, just silently degraded to searching only the few options already in the page).

Requires oscar.apps.dashboard.catalogue installed (it almost certainly already is — it's the products dashboard). If it isn't, turning this setting on will fail with a NoReverseMatch on dashboard:catalogue-product-lookup, not silently.

Adding a CTA (deliberately not built here)

This package intentionally ships no newsletter-subscribe or "promote this product" call-to-action anywhere in its templates — that's host-project UI/UX scope (placement, copy, branding), not something a reusable blog app should assume. If your project adds one, the natural places are oscar_blog/post_list.html/post_detail.html (override them) or a custom template tag included from there.

Development

uv sync
uv run pytest

tests/settings.py boots a full (stock) Oscar app stack — this package genuinely depends on Oscar's catalogue models, unlike a framework-agnostic library, so its tests can't run against bare Django alone.

Metadata

Release files for django-oscar-blog 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-oscar-blog 0.2.0
File Size Uploaded
django_oscar_blog-0.2.0.tar.gz 64.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-oscar-blog 0.2.0
File Interpreter ABI Platform
django_oscar_blog-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 81.3 kB

Release files / django_oscar_blog-0.2.0.tar.gz

Download URL django_oscar_blog-0.2.0.tar.gz
Size 64.8 kB
Tags Source
SHA-256 checksum
How to use checksums
6bfe9d3aa56e3aa5a4ec6f7589d26b67e5d3fd0ed04fc153d2148dcba6f16d78
BLAKE2b-256 checksum
How to use checksums
6760eb401b025ed35441fcc444829151fa4e8ca81796877174467a7b279c8d5a
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_blog-0.2.0-py3-none-any.whl

Download URL django_oscar_blog-0.2.0-py3-none-any.whl
Size 16.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c423092748a4254965dcd5d96c661f021c692fe6e6658354d459ca3a1d188da0
BLAKE2b-256 checksum
How to use checksums
a06efde0fe62908db78304feeb7781e77f23f20ce46e93d799a01ff9104aa2fb
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 history Release notifications | RSS feed

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

This release

0.2.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page