Online Document Scanning Using Python Django and Dynamic Web TWAIN
Django is a popular Python framework for web development. In this tutorial, we will create a web application using Django and Dynamic Web TWAIN.
This article is Part 4 in a 5-Part Series.
- Part 1 - Building Web Document Scanning Applications with ASP.NET Core MVC
- Part 2 - How to Scan and Upload Documents with Dynamic Web TWAIN and Node.js
- Part 3 - Scanning and Uploading Documents with Dynamic Web TWAIN and Go
- Part 4 - Online Document Scanning Using Python Django and Dynamic Web TWAIN
- Part 5 - How to Scan and Upload Documents in PHP Laravel Project
Prerequisites
- Python
-
Django
python -m pip install Django python -m django --version
- Dynamic Web TWAIN Trial License
Overall Steps
To integrate Django with Dynamic Web TWAIN, follow these steps:
- Create a Django project.
- Inside the project, create a Django app.
- Develop an HTML template to load the Dynamic Web TWAIN library, utilizing the template syntax to dynamically generate the library path.
- Configure the static resource files’ path.
Creating Your Project with Django
Open your terminal to initiate a Django project using the following command (applicable to Windows, Linux, and macOS):
python -m django startproject djangodwt
Upon completion, you’ll find the newly created project folder within your working directory.
Next, navigate into the djangodwt
directory and launch the app using the command below:
cd djangodwt
python manage.py runserver
Once the server starts successfully, open http://127.0.0.1:8000
in your web browser.
With these steps, you’ve successfully set up a simple Django project.
Integrating with Dynamic Web TWAIN
Creating the App
To develop your web scanner application, you should first create an app within your Django project.
python manage.py startapp dwt
Note: In Django, “project” and “app” have distinct meanings. An app is a web application that performs specific functions, whereas a project is a collection of apps that together comprise a particular website.
After this step, your project structure will look like this:
djangodwt
- djangodwt
- __pycache__
- asgi.py
- settings.py
- urls.py
- wsgi.py
- __init__.py
- dwt
- migrations
- __init__.py
- admin.py
- apps.py
- models.py
- tests.py
- views.py
- __init__.py
- db.sqlite3
- manage.py
Creating the View for Dynamic Web TWAIN
To develop our view, we will utilize a template. Conventionally, your template files should reside in {project_folder/templates/{app_named_folder}/}
. Let’s create one named index.html
.
<!DOCTYPE html>
<head>
<title>Dynamic Web Twain</title>
<meta charset="utf-8">
{% load static %}
{% csrf_token %}
<script type="text/javascript" src="{% static 'dynamsoft.webtwain.initiate.js' %}"></script>
<script type="text/javascript" src="{% static 'dynamsoft.webtwain.config.js' %}"></script>
<script type="text/javascript" src="{% static 'jquery-3.6.0.min.js' %}"></script>
</head>
<body>
<div id="app">
<div id="dwtcontrolContainer"></div>
<button onclick="scan()">Scan</button>
</div>
<script type="text/javascript">
var dwtObjct;
window.onload = function () {
if (Dynamsoft) {
Dynamsoft.DWT.AutoLoad = false;
Dynamsoft.DWT.UseLocalService = true;
Dynamsoft.DWT.Containers = [{ ContainerId: 'dwtcontrolContainer', Width: '640px', Height: '640px' }];
Dynamsoft.DWT.RegisterEvent('OnWebTwainReady', Dynamsoft_OnReady);
// https://www.dynamsoft.com/customer/license/trialLicense/?product=dcv&package=cross-platform
Dynamsoft.DWT.ProductKey = 'LICENSE-KEY';
Dynamsoft.DWT.ResourcesPath = 'static';
Dynamsoft.DWT.Load();
}
};
function Dynamsoft_OnReady() {
dwtObjct = Dynamsoft.DWT.GetWebTwain('dwtcontrolContainer');
}
function scan() {
if (dwtObjct) {
dwtObjct.SelectSourceAsync().then(function () {
return dwtObjct.AcquireImageAsync({
IfCloseSourceAfterAcquire: true // Scanner source will be closed automatically after the scan.
});
}).catch(function (exp) {
alert(exp.message);
});
}
}
</script>
</body>
Note that you’ll need a valid license key. Make sure to replace LICENSE-KEY
with your own to activate the scanner API. The ResourcesPath
should be the path to the dynamsoft.webtwain.initiate.js
and dynamsoft.webtwain.config.js
files, which we’ll address later.
Next, let’s edit the file dwt/views.py
by adding the following Python code:
from django.http import HttpResponse, request
from django import template
from django.shortcuts import render
import os
def index(request):
return render(request, 'dwt/index.html')
Within the app folder {project_folder}/dwt
, we create a file named urls.py
and insert the code below:
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index')
]
Then, we navigate to the project’s urls.py
file located in {project_folder}/{project_name}
and include the newly defined URL rules:
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('dwt.urls'))
]
Lastly, let’s configure the templates directory in settings.py
by specifying the template DIR
as follows:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')], # this field
'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',
],
},
},
]
Importing Dynamic Web TWAIN
It’s now time to integrate Dynamic Web TWAIN’s resource files into this project.
Steps:
- Under the project root, create a
static
folder. - Within the
static
folder, create adwt
folder. - From
<Dynamic Web TWAIN SDK PATH>/Resources
, copy the resource files to thestatic/
directory.
Next, add the following code to settings.py
to ensure the static/
directory is accessible:
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static")
]
With these steps, your web document scanning application using Dynamic Web TWAIN and Django should now be operational.
How to Upload Documents in Django
Let’s incorporate the front-end code to enable the uploading of scanned documents to the server.
function upload() {
dwtObjct.HTTPPort = 8000;
var CurrentPathName = unescape(location.pathname); // get current PathName in plain ASCII
var CurrentPath = CurrentPathName.substring(0, CurrentPathName.lastIndexOf("/") + 1);
var strActionPage = CurrentPath + "upload";
var strHostIP = "127.0.0.1";
var OnSuccess = function (httpResponse) {
alert("Succesfully uploaded");
};
var OnFailure = function (errorCode, errorString, httpResponse) {
alert(httpResponse);
};
var date = new Date();
var csrftoken = getCookie('csrftoken');
dwtObjct.SetHTTPFormField('csrfmiddlewaretoken', csrftoken);
dwtObjct.HTTPUploadThroughPostEx(
strHostIP,
dwtObjct.CurrentImageIndexInBuffer,
strActionPage,
date.getTime() + ".jpg",
1, // JPEG
OnSuccess, OnFailure
);
}
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
The upload
function is responsible for sending the scanned image to the server. It utilizes the HTTPUploadThroughPostEx
method for the upload process. The SetHTTPFormField
method is designated to set the form field for the CSRF token, while the getCookie
function retrieves the CSRF token from the cookie.
On the server side, uploaded documents can be managed in dwt/views.py
:
from django.http import HttpResponse, request
from django import template
from django.shortcuts import render
import os
from .models import Image
def index(request):
return render(request, 'dwt/index.html')
def upload(request):
if request.method == 'POST':
image = Image()
image.name = request.FILES['RemoteFile'].name
image.data = request.FILES['RemoteFile']
image.save()
return HttpResponse("Successful")
return HttpResponse("Failed")
def handle_uploaded_file(file, filename):
if not os.path.exists('upload/'):
os.mkdir('upload/')
with open('upload/' + filename, 'wb+') as destination:
for chunk in file.chunks():
destination.write(chunk)
return destination
Source Code
https://github.com/yushulx/web-twain-document-scan-management/blob/main/examples/python_upload