Getting Started¶
django-resume is a Django app that provides a simple way to create a resume within your Django website. It is designed to be easy to use and customize. You can write plugins to extend the functionality of your resume.
Custom plugins are added as Python code plus template files in your Django project. django-resume no longer supports database-backed plugins.
Plugins¶
This is the list of built-in plugins that come with django-resume:
About: A simple about section.
Cover: A cover page with some textual information and profile picture.
Education: Just the name of the school and the time you attended.
Identity: Your name, email, phone number, profile picture and social media links.
Permission Denied: The page that is shown when you try to access a part of the resume you need a token for.
Projects: A list of projects you have worked on.
Skills: A list of skills you have.
Page Theme: The django-resume theme used for built-in pages, editing UI, cover letters, and plugin templates (for example
plainorheadwind).Timeline: A timeline of your work experience.
Tokens: A token that you can use to access parts of the resume that are protected.
Text Formatting¶
Some built-in plugins render a small, sanitized markdown subset for user-provided text fields. This currently applies to text-heavy sections such as About, Cover, Projects, Timeline, and Permission Denied.
The supported formatting is intentionally limited to:
headings
bold
italic
links
line breaks
Rendered HTML is sanitized before it is marked safe, so raw HTML is not preserved and dangerous link protocols are removed.
Exporting to JSON Resume¶
Export a resume to the JSON Resume interchange format with:
python manage.py export_json_resume <slug> [--output FILE]
The document is written to stdout (or --output FILE); an export report –
mapped plugins, omitted plugins, dropped fields, and any omitted invalid dates –
is written to stderr. The command exits non-zero if the document fails
validation against the pinned JSON Resume v1.0.0 schema and writes no output.
Authenticated owners can also download the same export from
/<resume-prefix>/<slug>/json-resume/. The URL returns application/json
with an attachment filename of <slug>.json and is deliberately owner-only,
even if the public CV is tokenless.
Exports include a meta.django_resume extension envelope with django-resume
plugin data needed for exact same-application round trips. Standard JSON Resume
fields remain schema-valid; django-resume-only values such as display dates that
do not match JSON Resume’s date pattern stay in the extension envelope instead
of being forced into portable fields.
Treat django-resume exports as private backup or migration files, not public
registry uploads: the meta.django_resume.plugin_data envelope contains
application-private plugin data, including access-control plugin settings such
as CV tokens when those are present. Remove the meta.django_resume envelope
before sharing an export with third-party JSON Resume hosting or tooling that
does not need same-application restoration.
Rendering with JSON Resume Render Themes¶
django-resume has two different theme concepts:
A page theme is a Django template set used by django-resume pages and plugins. It affects the cover page, CV page, editing UI, and cover-letter content rendered by django-resume itself.
A JSON Resume render theme is an npm package from the JSON Resume ecosystem. It receives an exported JSON Resume document and returns a separate HTML rendering of that document.
Authenticated resume owners can choose from a curated JSON Resume render theme
catalog at /<resume-prefix>/<slug>/json-resume/themes/. The catalog is
deployment owned: each entry has a stable local key, an npm package name, and
an exact pinned version. The default page shows catalog cards with preview
images, package/version metadata, a local filter, a Preview render action,
and a separate Use render theme action.
For example, the local example server can open the Smaugustus Emberflame theme
catalog at
http://localhost:8000/resume/smaugustus-emberflame/json-resume/themes/.
Catalog images and public registry demos are illustrative only: the JSON
Resume registry may render different resume data or a different package version
than the deployment-pinned catalog entry. Use Preview render to see the
actual local output for the current resume and pinned package.
Preview render opens a private rendered HTML page for that catalog theme
without changing Resume.integration_data. Use render theme runs
npm install for the pinned catalog package and stores the selected catalog
key under Resume.integration_data["json_resume"]["theme"]. Existing resumes
that stored a selected theme as {"package": "jsonresume-theme-..."}
continue to render through that legacy package state.
Once a JSON Resume render theme is selected, owners can open
/<resume-prefix>/<slug>/json-resume/rendered/ to view the resume rendered
through that theme. This does not replace the normal /<slug>/cv/ page. The
normal CV route continues to use the resume’s page theme; the JSON Resume route
is a separate export/render artifact. The renderer receives a portable JSON
Resume projection: django-resume removes its private meta.django_resume
envelope before writing the temporary resume.json passed to the Node
renderer.
Developers and site operators can also render a static HTML file outside django-resume with the JSON Resume command-line tooling. First export the resume:
python manage.py export_json_resume <slug> --output resume.django-resume.json
Then install resumed and the theme package in a local npm project and render
the file:
npm install resumed jsonresume-theme-even
npx resumed render resume.django-resume.json --theme jsonresume-theme-even --output resume.html
This is useful for private local output, CI artifacts, or publishing a static
HTML file through a separate deployment process. The exported JSON contains
django-resume’s private meta.django_resume envelope, so strip it before
giving the file to third-party hosting, registry uploads, or any theme package
you do not fully trust:
jq 'del(.meta.django_resume) | if .meta == {} then del(.meta) else . end' \
resume.django-resume.json > resume.json
npx resumed render resume.json --theme jsonresume-theme-even --output resume.html
The command-line renderer is separate from the in-app preview. It uses whichever
resumed and theme package versions are installed in that npm project, while
the django-resume owner UI uses the deployment-pinned catalog and local theme
cache.
Theme packages execute JavaScript during rendering. Only authenticated owners
can preview, select, or render themes through these views, but catalog packages
should still be treated as trusted local code chosen by the site operator.
Preview and Use render theme may run npm install for the pinned catalog
package into django-resume’s configured local theme cache. Rendering itself uses
the local cache and does not fetch schemas, renderers, or themes from the
network. django-resume does not install themes for anonymous visitors, and
public CV pages or token-protected CV links do not imply permission to install
or render JSON Resume themes.
Rendered theme responses use a restrictive Content Security Policy by default:
inline styles are allowed for theme CSS, but browser-executed theme scripts and
remote stylesheet links are blocked. Operators who trust their curated render
themes and need browser-side theme JavaScript, such as date-duration custom
elements emitted by some themes, can set
DJANGO_RESUME_JSON_RESUME_ALLOW_THEME_SCRIPTS = True. That opt-in also
allows Google Fonts stylesheet links while keeping external scripts blocked.
Because inline theme scripts can still read the rendered page and trigger
allowed image requests, enabling this setting means trusting curated themes with
the rendered resume data.
Arbitrary npm theme search and install is disabled by default. Operators can
set DJANGO_RESUME_JSON_RESUME_ALLOW_DYNAMIC_THEME_INSTALL = True to show the
old npm search/install UI as a visibly separate development-discovery section.
That mode lets resume owners install packages named like
jsonresume-theme-* or @jsonresume/jsonresume-theme-* from npm, so it
should not be enabled for production deployments unless owner-triggered
third-party JavaScript execution is an accepted risk.
Importing from JSON Resume¶
Authenticated owners can import a JSON Resume file from the resume overview.
The import form creates a new resume owned by the current user from either an
uploaded resume.json file or an HTTP(S) JSON Resume URL, plus a
caller-supplied slug. Provide exactly one source. URL imports are limited to
public-address http or https URLs and use the same input-size limit as
file uploads. The optional name field overrides basics.name; when neither
is present, django-resume uses the slug as the resume name.
The browser import matches the management command’s create-only behavior. It
validates the incoming document against the pinned JSON Resume v1.0.0 schema,
rejects duplicate JSON object keys, requires a globally unique slug, and reports
mapped, restored, omitted, or lossy plugin data after a successful import.
By default, a django-resume round-trip export restores
meta.django_resume.plugin_data so application-private fields can survive a
backup or migration. Select Standard JSON Resume fields only to ignore that
private envelope and import only standard JSON Resume fields through plugin
adapters.
Signed provenance and update-in-place imports remain future work in the JSON Resume plan. Browser import currently creates a fresh resume; it does not merge or replace data in an existing resume.