Package: django-markupfield
An implementation of a custom MarkupField for Django.  A MarkupField is in
essence a TextField with an associated markup type.  The field also caches
its rendered value on the assumption that disk space is cheaper than CPU
cycles in a web application.InstallationThe recommended way to install django-markupfield is withpipIt is not necessary to add'markupfield'to yourINSTALLED_APPS, it
merely needs to be on yourPYTHONPATH. However, to use titled markup you
either add'markupfield'to yourINSTALLED_APPSor add the
corresponding translations to your project translation.RequirementsRequires Django >= 2.2 and 3.6+1.5.x is the last release to officially support Django < 2.2 or Python 2.71.4.x is the last release to officially support Django < 1.111.3.x is the last release to officially support Django 1.4 or Python 3.3SettingsTo best make use of MarkupField you should define theMARKUP_FIELD_TYPESsetting, a mapping of strings to callables that
‘render’ a markup type:import markdown
from docutils.core import publish_parts

def render_rest(markup):
    parts = publish_parts(source=markup, writer_name="html4css1")
    return parts["fragment"]

MARKUP_FIELD_TYPES = (
    ('markdown', markdown.markdown),
    ('ReST', render_rest),
)If you do not define aMARKUP_FIELD_TYPESthen one is provided with the
following markup types available:html:allows HTML, potentially unsafeplain:plain text markup, calls urlize and replaces text with linebreaksmarkdown:defaultmarkdownrenderer (only ifmarkdownis installed)restructuredtext:defaultReSTrenderer (only ifdocutilsis installed)It is also possible to overrideMARKUP_FIELD_TYPESon a per-field basis
by passing themarkup_choicesoption to aMarkupFieldin your model
declaration.UsageUsing MarkupField is relatively easy, it can be used in any model definition:from django.db import models
from markupfield.fields import MarkupField

class Article(models.Model):
    title = models.CharField(max_length=100)
    slug = models.SlugField(max_length=100)
    body = MarkupField()Articleobjects can then be created with any markup type defined inMARKUP_FIELD_TYPES:Article.objects.create(title='some article', slug='some-article',
                       body='*fancy*', body_markup_type='markdown')You will notice that a field namedbody_markup_typeexists that you did
not declare, MarkupField actually creates two extra fields herebody_markup_typeand_body_rendered.  These fields are always named
according to the name of the declaredMarkupField.ArgumentsMarkupFieldalso takes three optional arguments.  Eitherdefault_markup_typeandmarkup_typearguments may be specified but
not both.default_markup_type:Set a markup_type that the field will default to if one is not specified.
It is still possible to edit the markup type attribute and it will appear
by default in ModelForms.markup_type:Set markup type that the field will always use,editable=Falseis set
on the hidden field so it is not shown in ModelForms.markup_choices:A replacement list of markup choices to be used in lieu ofMARKUP_FIELD_TYPESon a per-field basis.escape_html:A flag (False by default) indicating that the input should be regarded
as untrusted and as such will be run through Django’sescapefilter.ExamplesMarkupFieldthat will default to using markdown but allow the user a choice:MarkupField(default_markup_type='markdown')MarkupFieldthat will use ReST and not provide a choice on forms:MarkupField(markup_type='restructuredtext')MarkupFieldthat will use a custom set of renderers:CUSTOM_RENDERERS = (
    ('markdown', markdown.markdown),
    ('wiki', my_wiki_render_func)
)
MarkupField(markup_choices=CUSTOM_RENDERERS)NoteWhen usingmarkdown, be sure to usemarkdown.markdownand not
themarkdown.Markdownclass, the class requires an explicitresetto function properly in some cases.  (See [issue #40](https://github.com/jamesturk/django-markupfield/issues/40)
for details.)Accessing a MarkupField on a modelWhen accessing an attribute of a model that was declared as aMarkupFielda specialMarkupobject is returned.  TheMarkupobject has three
parameters:raw:The unrendered markup.markup_type:The markup type.rendered:The rendered HTML version ofraw, this attribute is read-only.This object has a__unicode__method that callsdjango.utils.safestring.mark_safeonrenderedallowing MarkupField
objects to appear in templates as their rendered selfs without any template
tag or having to accessrendereddirectly.Assuming theArticlemodel above:>>> a = Article.objects.all()[0]
>>> a.body.raw
u'*fancy*'
>>> a.body.markup_type
u'markdown'
>>> a.body.rendered
u'<p><em>fancy</em></p>'
>>> print unicode(a.body)
<p><em>fancy</em></p>Assignment toa.bodyis equivalent to assignment toa.body.rawand
assignment toa.body_markup_typeis equivalent to assignment toa.body.markup_type.ImportantKeeping in mind thatbodyis MarkupField instance is particullary important withdefaultordefault_if_nonefilter for model that could be blank. Ifbody’srenderedisNoneor empty string ("") these filters willnotevaluatebodyas falsy to display default text:{{ a.body|default:"<missing body>" }}That’s becausebodyis regular non-NoneMarkupField instance. To letdefaultordefault_if_nonefilters to work evaluaterenderedMarkupField attribute instead. To prevent escaping HTML for the caserenderedis truethy, finish chain withsafefilter:{{ a.body.rendered|default:"<missing body>"|safe }}Notea.body.rendered is only updated when a.save() is called