My dear reader, how are you? السلام عليكم
Greatness is what happens when you aren’t afraid to relentlessly push yourself to tear down all your walls of limitations ― Edmond Mbiaka
This post explains the integration of Ace code editor with Django.
Few useful links to practically follow the project:
- Django-Ace-Integration GitHub repository — DirectMe
- Clone the application from GitHub using
git clone https://github.com/ArsalanShahid116/Django-Ace-Integration
SETTING-UP DJANGO PROJECT
Django-Ace-Integration$ virtualenv aceenv Django-Ace-Integration$ source aceenv/bin/activate (aceenv)Django-Ace-Integration$ pip3 install django (aceenv)Django-Ace-Integration$ pip3 freeze > requirements.txt # Create a Django project (aceenv)Django-Ace-Integration$ django-admin startproject config # Change project name (aceenv)Django-Ace-Integration$ mv config DjangoAce (aceenv)Django-Ace-Integration$ cd DjangoAce (aceenv)Django-Ace-Integration/DjangoAce$ django-admin startapp coder # list the qanda application in the list of installed apps in settings.py of project in config directory as shown below INSTALLED_APPS = [ 'coder', # add this 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ] # Configure Django project to use PostgreSQL. # open DjangoAce/config/settings.py and update the following DATABASE variable as follows DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'mymdb', 'USER': 'mymdb', 'PASSWORD': 'development', 'HOST': '127.0.0.1', 'PORT': '5432', } } # Configure Django project-wide templates and static files. # open DjangoAce/config/settings.py and update the following DATABASE variable as follows STATISFILES_DIR = [os.path.join(BASE_DIR, 'static'),] TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates'),], # add this 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] (aceenv)Django-Ace-Integration/DjangoAce$ pip3 install psycopg2 (aceenv)Django-Ace-Integration/DjangoAce$ python3 manage.py makemigrations (aceenv)Django-Ace-Integration/DjangoAce$ python3 manage.py migrate (aceenv)Django-Ace-Integration/DjangoAce$ python3 manage.py runserver
Check if development server is working by entering the following URL in browser http://127.0.0.1:8000/. It should be giving you something as shown in Figure 1. If it does, you are doing great. cheers!
A detail on individual Django project files is given in one of my earlier posts at DirectMe
Fig 1: Django Welcome Page
Follow the steps below to integrate Ace Code Editor into your Django Projects.
1) First of all, we will create a model as shown below
# open coder/models.py and add the following program from django.db import models from django.conf import settings class Code(models.Model): title = models.CharField(max_length=250) program = models.TextField() created = models.DateTimeField(auto_now_add=True) def __str__(self): return self.title
2) Register model in Django admin
# open coder/admin.py and add the following program from django.contrib import admin from .models import Code admin.site.register(Code)
3) Create a form to submit programs as shown below
# Create coder/forms.py and add the following program from django import forms from .models import Code class CodeForm(forms.ModelForm): class Meta: model = Code fields = ('program', 'title') widgets = { "program": forms.Textarea(), }
4) Add a view for the forms as shown below
# Create coder/views.py and add the following program from django.shortcuts import render from django.http import HttpResponse from .forms import CodeForm from .models import Code def add_code(request): if request.method == 'POST': form = CodeForm(request.POST) if form.is_valid(): form.save() return HttpResponse('Program added to database') else: return HttpResponse('not valid') else: # display empty form form = CodeForm() return render(request, 'coder/add_code.html', {'code_form': form})
5) Let us now add a template
# Create coder/templates/coder/add_code.html and add the following program {% extends "base.html" %} <title>{% block title %}DjangoAce{% endblock %}</title> {% block content %} <form id="coder_form" class="form" method="post"> {% csrf_token %} <div> Program title: <input type="text" name="title" required id="id_program"> <br> <br> </div> <div id="mydiv"> <textarea data-editor="twilight" name="program" cols="200" rows="20" required id="id_program"> </textarea> </div> <div> <input type="Submit" name="Submit" value="Submit"/> </div> </form> {% endblock %}
6) Let us now add a base template as shown below
# create coder/base.html and add the following program {% load static %} <!DOCTYPE html> <html> <head> <title>{% block title %}{% endblock %}</title> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" rel="stylesheet" crossorigin="anonymous"> <style> textarea{ height: 100%; width: 100%; -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */ -moz-box-sizing: border-box; /* Firefox, other Gecko */ box-sizing: border-box; /* Opera/IE 8+ */ } #mydiv{ height: 500px; width: 1000px; } </style> </head> <body> <header> <nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark"> <div class="navbar-brand">DjangoAce</div> </nav> </header> <br /> <br /> <br /> <br /> <div class="container"> <div id="content"> {% block content %} {% endblock %} </div> <script src="{% static "ace/ace.js" %}"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script> <script> $(function () { $('textarea[data-editor]').each(function () { var textarea = $(this); var theme = textarea.data('editor'); var editDiv = $('<div>', { position: 'absolute', width: textarea.width(), height: textarea.height(), 'class': textarea.attr('class') }).insertBefore(textarea); textarea.css('visibility', 'hidden'); ace.require("ace/ext/language_tools"); var editor = ace.edit(editDiv[0]); editor.setOptions({enableLiveAutocompletion: true, cursorStyle: 'ace', showGutter: true, showLineNumbers: true}); editor.setFontSize(16); editor.getSession().setValue(textarea.val()); editor.getSession().setMode("ace/mode/python"); editor.setTheme("ace/theme/" + theme); textarea.closest('form').submit(function () { textarea.val(editor.getSession().getValue()); }) }); }); </script> </body> </html>
7) Add statis files. Create a directory in coder/static, name it as ace and add the ace source files from the following link DirectMe into it.
8) Add a route to the application and views as shown below
# Open coder/urls.py and add the following program from django.urls import path from . import views from django.contrib.auth import views as auth_views urlpatterns = [ path('add', views.add_code, name='add_code'), ] # open config/urls.py and add the following program from django.contrib import admin from django.urls import path, include from django.conf import settings from django.conf.urls.static import static import coder.urls urlpatterns = [ path('admin/', admin.site.urls), path('coder/', include('coder.urls')), ]
If you run the development server at this point in time you should be able to see the added functionalities at http://127.0.0.1:8000/coder/add
I hope you find this tutorial useful. If you find any errors or feel any need for improvement, let me know in your comments below.
Signing off for today. Stay tuned and I will see you next week! Happy learning.