{"id":13419267,"url":"https://github.com/withlogicco/django-prose","last_synced_at":"2025-04-05T14:04:07.289Z","repository":{"id":42004442,"uuid":"164243659","full_name":"withlogicco/django-prose","owner":"withlogicco","description":"Wonderful rich-text editing for your Django project","archived":false,"fork":false,"pushed_at":"2024-04-05T09:16:12.000Z","size":302,"stargazers_count":163,"open_issues_count":0,"forks_count":11,"subscribers_count":6,"default_branch":"main","last_synced_at":"2024-04-09T09:23:18.676Z","etag":null,"topics":["django","django-wysiwyg","python","trix","wysiwyg"],"latest_commit_sha":null,"homepage":"https://stateofprogress.blog/2023/02/01/django-prose-wonderful-rich-text-content-editing-for-django","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/withlogicco.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2019-01-05T19:09:31.000Z","updated_at":"2024-07-17T13:01:41.132Z","dependencies_parsed_at":"2023-02-17T07:31:44.503Z","dependency_job_id":"bfa49da8-4944-44fd-a443-0f4d55c9c511","html_url":"https://github.com/withlogicco/django-prose","commit_stats":null,"previous_names":["parisk/django-prose"],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/withlogicco%2Fdjango-prose","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/withlogicco%2Fdjango-prose/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/withlogicco%2Fdjango-prose/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/withlogicco%2Fdjango-prose/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/withlogicco","download_url":"https://codeload.github.com/withlogicco/django-prose/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247345850,"owners_count":20924102,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["django","django-wysiwyg","python","trix","wysiwyg"],"created_at":"2024-07-30T22:01:13.616Z","updated_at":"2025-04-05T14:04:07.267Z","avatar_url":"https://github.com/withlogicco.png","language":"Python","funding_links":[],"categories":["Python","Third-Party Packages"],"sub_categories":["Editors"],"readme":"# Django Prose\n\n![PyPI - Downloads](https://img.shields.io/pypi/dw/django-prose?color=purple) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/django-prose)\n\nDjango Prose provides your Django applications with wonderful rich-text editing capabilities.\n\n## Requirements\n\n- Python 3.8 or later\n- Django 3.2 or later\n- Bleach 4.0 or later\n\n## Getting started\n\nTo get started with Django Prose, all you need to do is follow **just four steps**.\n\n1. **Install `django-prose`**\n    \n    We use and suggest using Poetry, although Pipenv and plain pip will work seamlessly as well\n    \n    ```console\n    poetry add django-prose\n    ```\n\n2. **Add to `INSTALLED_APPS`**\n    \n    Add `prose` in your Django project's installed apps (example: [`example/example/settings.py`](https://github.com/withlogicco/django-prose/blob/9e24cc794eae6db48818dd15a483d106d6a99da0/example/example/settings.py#L46)):\n    \n    ```python\n    INSTALLED_APPS = [\n        # Django stock apps (e.g. 'django.contrib.admin')\n    \n        'prose',\n    \n        # your application's apps\n    ]\n    ```\n\n3. **Run migrations**\n\n    This is required so you can use Django Prose's built-in Document model:\n  \n    ```console\n    python manage.py migrate prose\n    ```\n\n4. **Include URLs**\n\n    You need to edit the main `urls.py` file of your Django project and include `prose.urls`:\n    \n    ```python\n    urlpatterns = [\n        path('admin/', admin.site.urls),\n        # other urls ...\n        path(\"prose/\", include(\"prose.urls\")),\n    ]\n    ```\n\nNow, you are ready to go 🚀.\n\n## Usage\n\nThere are different ways to use Django prose according to your needs. We will examine all of them here.\n\n### Rendering rich-text in templates\n\nRich text content essentially is HTML. For this reason it needs to be manually marked as [`safe`](https://docs.djangoproject.com/en/4.2/ref/templates/builtins/#safe), when rendered in Django templates. Example:\n\n```django\n{{ document.content | safe}}\n```\n\n### Small rich-text content\n\nYou might want to add rich-text content in a model that is just a few characters (e.g. 140), like an excerpt from an article. In that case we suggest using the `RichTextField`. Example:\n\n```py\nfrom django.db import models\nfrom prose.fields import RichTextField\n\nclass Article(models.Model):\n    excerpt = RichTextField()\n```\n\nAs mentioned above, you need to mark the article excerpt as `safe`, in order to render it:\n\n```django\n\u003cdiv class=\"article-excerpt\"\u003e{{ article.excerpt | safe}}\u003c/div\u003e\n```\n\n### Large rich-text content\n\nIn case you want to store large rich-text content, like the body of an article, which can span to quite a few thousand characters, we suggest you use the `AbstractDocument` model. This will save large rich-text content in a separate database table, which is better for performance. Example:\n\n```py\nfrom django.db import models\nfrom prose.fields import RichTextField\nfrom prose.models import AbstractDocument\n\nclass ArticleContent(AbstractDocument):\n    pass\n\nclass Article(models.Model):\n    excerpt = RichTextField()\n    body = models.OneToOneField(ArticleContent, on_delete=models.CASCADE)\n```\n\nSimilarly here as well, you need to mark the article's body as `safe`, in order to render it:\n\n```django\n\u003cdiv class=\"article-body\"\u003e{{ article.body.content | safe}}\u003c/div\u003e\n```\n\n### Forms with rich-text editing\n\nYou can create forms for your Django Prose models, to provide rich-text editing functionality. In that case, you will also need to render `form.media`, to load Trix with its stylesheets.\n\n```django\n\u003cform  method=\"POST\" \u003e\n  {% csrf_token %}\n  \n  {{ form.as_p }}\n  {{ form.media }}\n  \n  \u003cbutton type=\"submit\"\u003eSubmit\u003c/button\u003e\n\u003c/form\u003e\n```\n\nThe same is true also, if you are rendering the forms field manually.\n\n### Attachments\n\nDjango Prose can also handle uploading attachments with drag and drop. To set this up, first you need to:\n\n- [x] Set up the `MEDIA_ROOT` and `MEDIA_URL` of your Django project (example in [`example/example/settings.py`](https://github.com/withlogicco/django-prose/blob/9e24cc794eae6db48818dd15a483d106d6a99da0/example/example/settings.py#L130-L131)))\n- [x] Include the Django Prose URLs (example in [`example/example/urls.py`](https://github.com/withlogicco/django-prose/blob/9e24cc794eae6db48818dd15a483d106d6a99da0/example/example/urls.py#L13-L14))\n- [x] (Optional) Set up a different Django storage to store your files (e.g. S3)\n\n- Attachments are uploaded with a path structure of `/YEAR/MONTH/DATE/UUID.EXT`\n- By default, only files 5MB or less are allowed.\n\nAllowed file size can be overridden by setting `PROSE_ATTACHMENT_ALLOWED_FILE_SIZE` in your Django project's settings file.\n\n```python\n# File size in megabytes\nPROSE_ATTACHMENT_ALLOWED_FILE_SIZE = 15\n```\n\n### Full example\n\nYou can find a full example of a blog, built with Django Prose in the [`example`](./example/) directory.\n\n## 🔒 A note on security\n\nAs you can see in the examples above, what Django Prose does is provide you with a user friendly editor ([Trix](https://trix-editor.org/)) for your rich text content and then store it as HTML in your database. Since you will mark this HTML as safe in order to use it in your templates, it needs to be **sanitised**, before it gets stored in the database.\n\nFor this reason Django Prose is using [Bleach](https://bleach.readthedocs.io/en/latest/) to only allow the following tags and attributes:\n\n- **Allowed tags**: `p`, `ul`, `ol`, `li`, `strong`, `em`, `div`, `span`, `a`, `blockquote`, `pre`, `figure`, `figcaption`, `br`, `code`, `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `picture`, `source`, `img`\n- **Allowed attributes**: `alt`, `class`, `id`, `src`, `srcset`, `href`, `media`\n\n## Screenshots\n\n### Django Prose Documents in Django Admin\n\n![Django Prose Document in Django Admin](./docs/django-admin-prose-document.png)\n\n## Video tutorial\n\nIf you are more of a video person, you can watch our video showcasing how to **Create a blog using Django Prose** on YouTube\n\n[![Watch the video](https://img.youtube.com/vi/uICZjUpAbhQ/hqdefault.jpg)](https://youtu.be/uICZjUpAbhQ)\n\n## Real world use cases\n- **Remote Work Café**: Used to edit location pagess, like [Amsterdam | Remote Work Café](https://remotework.cafe/locations/amsterdam/)\n- In production by multiple clients of [LOGIC](https://withlogic.co), from small companies to the public sector.\n\nIf you are using Django Prose in your application too, feel free to open a [Pull Request](https://github.com/withlogicco/django-prose/pulls) to include it here. We would love to have it.\n\n## Development for Django Prose\n\nIf you plan to contribute code to Django Prose, this section is for you. All development tooling for Django Prose has been set up with Docker and Development Containers.\n\nTo get started run these commands in the provided order:\n\n```console\ndocker compose run --rm migrate\ndocker compose run --rm createsuperuser\ndocker compose up\n```\n\nIf you are using Visual Studio code, just open this repository in a container using the [`Dev Containers: Open Folder in Container`](https://code.visualstudio.com/docs/devcontainers/containers#_quick-start-open-an-existing-folder-in-a-container).\n\n---\n\n\u003cp align=\"center\"\u003e\n  \u003ci\u003e🦄 Built with \u003ca href=\"https://withlogic.co/\"\u003eLOGIC\u003c/a\u003e. 🦄\u003c/i\u003e\n\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwithlogicco%2Fdjango-prose","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwithlogicco%2Fdjango-prose","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwithlogicco%2Fdjango-prose/lists"}