Showcase

Inside My Django Blog

10 min read

A complete look at the Django publishing system behind my personal blog, from structured articles and media to Admin workflows, private JSON imports, SEO, and multi-site publishing.

I built this blog because I wanted one comfortable place to write, review, and publish articles. It runs inside my Django website, so I can manage the words, images, links, and publishing steps without maintaining a separate content system.

This article shows you how it all works. I cover the public blog, my private Admin area, the JSON import feature, images, search, and SEO. I also use every content block available in the editor, which means the page itself is a live showcase of the blog.

What I wanted the blog to solve

I wanted writing to stay simple, but I did not want every article to become one huge text box. Instead, I build an article from smaller pieces such as headings, normal text, code, images, checklists, callouts, social embeds, and FAQs.

This makes editing much easier. I can move an image, replace a code example, or remove a callout without disturbing the rest of the article. It also helps every article keep the same clean style.

I can be flexible with the content while the blog takes care of how each part looks and behaves.

A public reading experience built for real articles

When you open the blog, you can browse all articles or narrow them down by category, tag, author, or year. I also added search and filters for times when the archive gets longer. These basic controls still work if JavaScript is unavailable; JavaScript only makes them feel quicker.

Inside an article, you get breadcrumbs, a table of contents, reading time, related posts, and previous or next links when they are available. You can also switch reading mode, copy or share the link, print a clean version, and open larger images in a lightbox. The lightbox works with a keyboard too.

Here is a simple overview of the main pages.

PageWhat you can do there
Blog archiveBrowse, search, filter, and discover articles
Article pageRead an article and use its navigation and media tools
Category, tag, and author pagesFind more writing about one topic or by one person
RSS feedFollow new articles in a feed reader
Public oli-dev0 Blog article with reading metadata, table of contents, and structured content
The public article experience Server-rendered content, reading tools, navigation, and responsive media share one focused layout.

Light and dark presentation without duplicate content

I designed the blog for both the light and dark themes of my personal site. The words and layout stay the same, while tables, code, callouts, embeds, captions, and controls adjust to the chosen theme. You can compare the same section in both themes below.

  1. The same oli-dev0 Blog article displayed in dark theme
  2. The same oli-dev0 Blog article displayed in light theme
One article, two themes The content and layout stay matched while the personal-site theme changes.

Structured content blocks, not arbitrary page markup

I chose a clear set of content blocks instead of letting articles contain any custom code. That gives me enough freedom for detailed writing without making the pages hard to maintain.

  • Headings and rich text hold the main story, lists, links, quotes, and tables.
  • Code, checklists, callouts, and FAQs break up instructions and important details.
  • Images and comparisons let me show a real screen or compare two matching views.
  • Source, link group, and internal link blocks give readers clear places to continue.
  • Social embeds can show one public YouTube video, X post, or Reddit post.

I arrange these blocks in the order I want inside Django Admin. The blog then checks each block and displays it in the right style.

  • Write the article as small, meaningful content blocks
  • Add descriptive image text and captions where they help
  • Preview the saved draft in the correct website design
  • Resolve publication checks before making the article public

The Django Admin is the editorial workspace

I manage the blog from a private area built with Django Admin. To start an article, I fill in a short form with the title, website, article type, category, and author. I can then add and reorder content blocks, choose images, connect related articles, and preview the saved draft in the real website design.

I also manage authors, categories, tags, reusable images, and image comparisons from the Admin. When an article is ready, I can send it for review, publish it now, schedule it for later, or take it offline again. Django permissions decide who is allowed to use each action.

I keep this area private because it is my publishing workspace, not a page for regular visitors.

Django Admin article editor showing publishing actions, article details, author, and SEO fields
Article details and publishing controls I can manage the article details, search presentation, preview, review, scheduling, and publishing actions from the same screen.
Django Admin article editor showing category, tags, featured image, canonical site, and publication status
Organization and publication status Categories, tags, the featured image, the main website, and the current publishing state stay together.
Django Admin article editor showing ordered rich-text and heading content blocks
The block editor I build each article from ordered blocks and can add, edit, move, collapse, or remove them independently.

A private JSON import turns prepared articles into drafts

For a longer article, I often prefer preparing everything outside the browser. I can then import one JSON file together with its images. The blog checks the complete package and shows me a private review page before it creates anything.

On that review page, I can check the author, category, tags, website, content blocks, links, and images. If a category or tag does not exist yet, the Admin asks me to confirm before creating it. Importing always makes a new draft. It never publishes an article or replaces existing work by itself.

The example below shows the basic shape of an import file. The complete file follows the same pattern and lists every block and image in order.

{
  "format": "blog-article-import",
  "version": 2,
  "article": {
    "title": "A prepared article",
    "slug": "a-prepared-article",
    "type": "article",
    "summary": "A short, useful summary.",
    "author": {"slug": "oli-dev0"},
    "category": {"name": "Projects", "slug": "projects"},
    "publication_sites": ["my_website"],
    "canonical_site": "my_website",
    "blocks": [
      {"type": "rich_text", "body": "<p>The opening paragraph.</p>"}
    ]
  },
  "assets": [],
  "comparisons": []
}
A compact Blog article import example
Django Admin import review showing the new draft notice, article details, author, category, publication sites, and tag choices
Checking the article details I review the imported article, author, category, websites, and tags before creating the draft.
Django Admin import review showing SEO details, publication information, related articles, and the first ordered content blocks
Reviewing SEO and content blocks The review shows me how the search details and ordered article blocks will be imported.
Django Admin import review showing the remaining ordered content blocks and a valid referenced-image result
Checking the remaining content and images I can confirm the rest of the block order and see whether each referenced image passed validation.

Images are reusable, processed, and accessible

I manage images separately so each upload keeps its own name, alternative text, caption, and processing status. A featured image represents the whole article in cards and social previews. A body image belongs to one particular part of the story.

When I upload an image, the blog checks it and creates smaller WebP versions for different screen sizes. It never stretches a small original into a larger file. Readers can open body images in a lightbox, and I can keep two matching images together for a before-and-after or theme comparison.

I also separate useful images from decoration. An image that adds information needs alternative text for people who cannot see it. A purely decorative image uses empty alternative text and cannot be added as a normal article image.

SEO and discovery come from the publishing model

I built search and sharing details into the normal publishing flow. Every public article gets a clean main URL, one clear page title, a search description, social sharing details, and structured data that describes the article in a machine-readable way.

Only published articles for the current website can appear in public search results. I include the right articles in the sitemap and RSS feed, while keeping drafts, previews, Admin pages, and internal search pages out. Category, tag, and author pages give readers useful ways to discover more without creating endless thin pages.

I also make sure the important words and links arrive in the first page response. JavaScript improves search filters, sharing, embeds, themes, and image viewing, but you do not need it to read the article.

One Blog application can serve different websites

I built the Blog once inside my shared Django project, but I can use it on more than one website. Each website still keeps its own header, layout, colours, and personality. I can publish an article on one or more supported sites and choose which one owns the main public URL.

The blog checks that categories, tags, related articles, internal links, previews, and feeds make sense for every website I select. This lets me reuse the useful parts without forcing all my websites to look the same.

What this project demonstrates

This project shows the full path from writing a draft to helping someone discover and read it. Behind the scenes, I worked on permissions, safe file uploads, image sizes, keyboard-friendly controls, search, RSS feeds, sitemaps, social sharing, and support for more than one website.

I could have used a separate headless CMS or a JavaScript page builder. Those tools can offer a more visual editor, but they would also give me another system to run and connect. I chose Django models and templates because they keep everything together and easy for me to understand. For my own publishing workflow, that is the simpler and more maintainable choice.

Frequently asked questions

Is the blog a separate CMS?

No. I built it as a Django application inside the same project as my websites. I use Django Admin as my private writing and publishing area.

Does every article need every content block?

No. I use every block in this showcase on purpose. For a normal article, I only add the blocks that make the subject easier to understand.

Does the public article depend on JavaScript?

No. I send the main content, links, forms, and navigation as part of the page itself. JavaScript only adds extras such as quicker filters, social embeds, sharing, and the image lightbox.

Can I style the blog to match my website?

Yes. The blog can use its own styling while still fitting naturally into the rest of your website.

Can different websites have different blog designs?

Yes. Each website can have its own blog stylesheet, layout, colours, spacing, and typography.

What happens if a website does not have custom blog styles?

It uses the default blog styling as a fallback, so the blog still looks consistent and usable.

Do I need to rebuild the blog for every website?

No. The blog features and content can stay shared while each website adds only the visual changes it needs.

Back to blog

Expanded article image

Loading image…