Add Stack Overflow's "Pagedown" Markdown editor to your Django Admin or custom form.
Version >= 2.0.0 of django-pagedown requires Django 2.1.0 or above (previous versions should support Django all the way back to around 1.1).
- Get the code:
pip install django-pagedown - Add
pagedown.apps.PagedownConfigto yourINSTALLED_APPSinsettings.py - Configure and collect the static files:
python manage.py collectstatic
The widget can be used both inside the django admin or independendly.
If you want to use the pagedown editor in a django admin field, there are numerous possible approaches:
-
To use it in all
TextField's in your admin form:from django.contrib import admin from django.db import models from pagedown.widgets import AdminPagedownWidget class AlbumAdmin(admin.ModelAdmin): formfield_overrides = { models.TextField: {'widget': AdminPagedownWidget }, }
-
To only use it on particular fields, first create a form (in
forms.py):from django import forms from pagedown.widgets import AdminPagedownWidget from music.models import Album class AlbumForm(forms.ModelForm): name = forms.CharField(widget=AdminPagedownWidget()) description = forms.CharField(widget=AdminPagedownWidget()) class Meta: model = Album fields = "__all__"
and in your
admin.py:from django.contrib import admin from forms import FooModelForm from models import FooModel @admin.register(FooModel) class FooModelAdmin(admin.ModelAdmin): form = FooModelForm fields = "__all__"
To use the widget outside of the django admin, first create a form similar to the above but using the basic PagedownWidget:
from django import forms
from pagedown.widgets import PagedownWidget
from music.models import Album
class AlbumForm(forms.ModelForm):
name = forms.CharField(widget=PagedownWidget())
description = forms.CharField(widget=PagedownWidget())
class Meta:
model = Album
fields = ["name", "description"]Then define your urls/views:
from django.views.generic import FormView
from django.conf.urls import patterns, url
from music.forms import AlbumForm
urlpatterns = patterns('',
url(r'^$', FormView.as_view(template_name="baz.html",
form_class=AlbumForm)),)then create the template and load the javascipt and css required to create the editor:
<html>
<head>
{{ form.media }}
</head>
<body>
<form ...>
{{ form }}
</form>
</body>
</html>If you want to customize the widget, the easiest way is to simply extend it:
from pagedown.widgets import PagedownWidget
class MyNewWidget(PagedownWidget):
template_name = '/custom/template.html'
class Media:
css = {
'all': ('custom/stylesheets.css',)
}
js = ('custom/javascript.js',)contrib.markdown was deprecated in Django 1.5 meaning you can no longer use the markdown filter in your template by default.
@wkcd has a good example of how to overcome by installing django-markdown-deux:
{% extends 'base.html' %}
{% load markdown_deux_tags %}
...
<p>{{ entry.body|markdown }}</p>
...You can enable image uploads, allowing your users to upload new images to the server and have them automatically inserted into the Pagedown widget (instead of just adding image URLs):
To do so:
- Make sure you have set a
MEDIA_URLandMEDIA_ROOTso that uploads will be propertly saved - Add
PAGEDOWN_IMAGE_UPLOAD_ENABLED=Trueto your settings - Include the pagedown paths in your
urls.pyso that the upload endpoint is available
# ...
urlpatterns = [
path('', include('pagedown.urls')),
# ...
]This will add the URL /pagedown/image-upload/ endpoint to your project. You can see the default view that handles the upload here
The following options are available via your settings to tweak how the image upload works:
PAGEDOWN_IMAGE_UPLOAD_PATHcan be used to change the path within your media root (default ispagedown-uploads)PAGEDOWN_IMAGE_UPLOAD_EXTENSIONScan be used to limit the extensions allowed for upload (default isjpg,jpeg,png,webp)PAGEDOWN_IMAGE_UPLOAD_UNIQUEcan be used to ensure all uploads are stored in a uniquely named subfolder, e.g.f748e009-c3cb-40f3-abf2-d103ab0ad259/my-file.png(default isFalse)
Check out the pagedown_init.js script to see how the upload is being performed on the client side.
You can see a fully-fledged example of the widget in django-pagedown-example

