├── config
├── __init__.py
├── settings
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── base.cpython-310.pyc
│ │ ├── env.cpython-310.pyc
│ │ └── __init__.cpython-310.pyc
│ └── base.py
├── __pycache__
│ ├── urls.cpython-310.pyc
│ ├── wsgi.cpython-310.pyc
│ ├── __init__.cpython-310.pyc
│ └── settings.cpython-310.pyc
├── asgi.py
├── wsgi.py
└── urls.py
├── task
├── __init__.py
├── migrations
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-310.pyc
│ │ └── 0001_initial.cpython-310.pyc
│ └── 0001_initial.py
├── tests.py
├── __pycache__
│ ├── admin.cpython-310.pyc
│ ├── apps.cpython-310.pyc
│ ├── urls.cpython-310.pyc
│ ├── views.cpython-310.pyc
│ ├── __init__.cpython-310.pyc
│ └── models.cpython-310.pyc
├── apps.py
├── urls.py
├── admin.py
├── templates
│ └── excel_page.html
├── models.py
└── views.py
├── .gitignore
├── requirements.txt
└── manage.py
/config/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/task/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | env.py
2 | env
--------------------------------------------------------------------------------
/task/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/config/settings/__init__.py:
--------------------------------------------------------------------------------
1 | from .base import *
2 | from .env import *
--------------------------------------------------------------------------------
/task/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/task/__pycache__/admin.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/susilnem/Export-data-in-Excel-using-Multithreading/HEAD/task/__pycache__/admin.cpython-310.pyc
--------------------------------------------------------------------------------
/task/__pycache__/apps.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/susilnem/Export-data-in-Excel-using-Multithreading/HEAD/task/__pycache__/apps.cpython-310.pyc
--------------------------------------------------------------------------------
/task/__pycache__/urls.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/susilnem/Export-data-in-Excel-using-Multithreading/HEAD/task/__pycache__/urls.cpython-310.pyc
--------------------------------------------------------------------------------
/task/__pycache__/views.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/susilnem/Export-data-in-Excel-using-Multithreading/HEAD/task/__pycache__/views.cpython-310.pyc
--------------------------------------------------------------------------------
/config/__pycache__/urls.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/susilnem/Export-data-in-Excel-using-Multithreading/HEAD/config/__pycache__/urls.cpython-310.pyc
--------------------------------------------------------------------------------
/config/__pycache__/wsgi.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/susilnem/Export-data-in-Excel-using-Multithreading/HEAD/config/__pycache__/wsgi.cpython-310.pyc
--------------------------------------------------------------------------------
/task/__pycache__/__init__.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/susilnem/Export-data-in-Excel-using-Multithreading/HEAD/task/__pycache__/__init__.cpython-310.pyc
--------------------------------------------------------------------------------
/task/__pycache__/models.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/susilnem/Export-data-in-Excel-using-Multithreading/HEAD/task/__pycache__/models.cpython-310.pyc
--------------------------------------------------------------------------------
/config/__pycache__/__init__.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/susilnem/Export-data-in-Excel-using-Multithreading/HEAD/config/__pycache__/__init__.cpython-310.pyc
--------------------------------------------------------------------------------
/config/__pycache__/settings.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/susilnem/Export-data-in-Excel-using-Multithreading/HEAD/config/__pycache__/settings.cpython-310.pyc
--------------------------------------------------------------------------------
/task/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class TaskConfig(AppConfig):
5 | default_auto_field = "django.db.models.BigAutoField"
6 | name = "task"
7 |
--------------------------------------------------------------------------------
/config/settings/__pycache__/base.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/susilnem/Export-data-in-Excel-using-Multithreading/HEAD/config/settings/__pycache__/base.cpython-310.pyc
--------------------------------------------------------------------------------
/config/settings/__pycache__/env.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/susilnem/Export-data-in-Excel-using-Multithreading/HEAD/config/settings/__pycache__/env.cpython-310.pyc
--------------------------------------------------------------------------------
/config/settings/__pycache__/__init__.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/susilnem/Export-data-in-Excel-using-Multithreading/HEAD/config/settings/__pycache__/__init__.cpython-310.pyc
--------------------------------------------------------------------------------
/task/migrations/__pycache__/__init__.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/susilnem/Export-data-in-Excel-using-Multithreading/HEAD/task/migrations/__pycache__/__init__.cpython-310.pyc
--------------------------------------------------------------------------------
/task/migrations/__pycache__/0001_initial.cpython-310.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/susilnem/Export-data-in-Excel-using-Multithreading/HEAD/task/migrations/__pycache__/0001_initial.cpython-310.pyc
--------------------------------------------------------------------------------
/task/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 | from .views import ExcelPageView, ExportExcelfile
3 | urlpatterns = [
4 | path("", ExcelPageView.as_view()),
5 | path("download/", ExportExcelfile, name="export"),
6 | ]
7 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | asgiref==3.5.2
2 | autopep8==1.7.0
3 | Django==4.1.2
4 | et-xmlfile==1.1.0
5 | openpyxl==3.0.10
6 | psycopg2-binary==2.9.4
7 | pycodestyle==2.9.1
8 | sqlparse==0.4.3
9 | toml==0.10.2
10 | xlwt==1.3.0
11 |
--------------------------------------------------------------------------------
/task/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | from task.models import FileType, Jobs, Applicants, Documents, JobsCategory
3 | # Register your models here.
4 |
5 | admin.site.register(Jobs)
6 | admin.site.register(Applicants)
7 | admin.site.register(Documents)
8 | admin.site.register(FileType)
9 | admin.site.register(JobsCategory)
10 |
--------------------------------------------------------------------------------
/task/templates/excel_page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Excel Export
6 |
7 |
8 |
9 |
10 | Export the data in Excel
11 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/config/asgi.py:
--------------------------------------------------------------------------------
1 | """
2 | ASGI config for config project.
3 |
4 | It exposes the ASGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/4.1/howto/deployment/asgi/
8 | """
9 |
10 | import os
11 |
12 | from django.core.asgi import get_asgi_application
13 |
14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
15 |
16 | application = get_asgi_application()
17 |
--------------------------------------------------------------------------------
/config/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for config project.
3 |
4 | It exposes the WSGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/4.1/howto/deployment/wsgi/
8 | """
9 |
10 | import os
11 |
12 | from django.core.wsgi import get_wsgi_application
13 |
14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
15 |
16 | application = get_wsgi_application()
17 |
--------------------------------------------------------------------------------
/manage.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | """Django's command-line utility for administrative tasks."""
3 | import os
4 | import sys
5 |
6 |
7 | def main():
8 | """Run administrative tasks."""
9 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
10 | try:
11 | from django.core.management import execute_from_command_line
12 | except ImportError as exc:
13 | raise ImportError(
14 | "Couldn't import Django. Are you sure it's installed and "
15 | "available on your PYTHONPATH environment variable? Did you "
16 | "forget to activate a virtual environment?"
17 | ) from exc
18 | execute_from_command_line(sys.argv)
19 |
20 |
21 | if __name__ == "__main__":
22 | main()
23 |
--------------------------------------------------------------------------------
/config/urls.py:
--------------------------------------------------------------------------------
1 | """config URL Configuration
2 |
3 | The `urlpatterns` list routes URLs to views. For more information please see:
4 | https://docs.djangoproject.com/en/4.1/topics/http/urls/
5 | Examples:
6 | Function views
7 | 1. Add an import: from my_app import views
8 | 2. Add a URL to urlpatterns: path('', views.home, name='home')
9 | Class-based views
10 | 1. Add an import: from other_app.views import Home
11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
12 | Including another URLconf
13 | 1. Import the include() function: from django.urls import include, path
14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
15 | """
16 | from django.contrib import admin
17 | from django.urls import path, include
18 | from django.conf import settings
19 | from django.conf.urls.static import static
20 |
21 | urlpatterns = [
22 | path("admin/", admin.site.urls),
23 | path("", include('task.urls'))
24 | ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
25 |
--------------------------------------------------------------------------------
/task/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 | from django.contrib.auth.models import User
3 | # Create your models here.\
4 |
5 |
6 | JOB_TYPE = (("Fulll time", "Full time"), ("Part time",
7 | "Part time"), ("Internship", "Internship"))
8 | CATEGORY = (("Citizenship", "Citizenship"),
9 | ("passport", "passport"), ("cv", "cv"))
10 |
11 |
12 |
13 | class JobsCategory(models.Model):
14 | title = models.CharField(max_length=300)
15 |
16 | def __str__(self):
17 | return self.title
18 |
19 |
20 | class Jobs(models.Model):
21 | user = models.ForeignKey(User, on_delete=models.CASCADE)
22 | title = models.CharField(max_length=300)
23 | location = models.CharField(max_length=150)
24 | type = models.CharField(choices=JOB_TYPE, max_length=10)
25 | category = models.ForeignKey(JobsCategory, on_delete=models.CASCADE)
26 | company_name = models.CharField(max_length=100)
27 | salary = models.IntegerField(default=0, blank=True)
28 |
29 | def __str__(self):
30 | return self.title
31 |
32 |
33 | class FileType(models.Model):
34 | type = models.FileField(upload_to="documents")
35 |
36 | def __str__(self):
37 | return self.type.name
38 |
39 |
40 | class Documents(models.Model):
41 | category = models.CharField(max_length=255, choices=CATEGORY, null=False)
42 | file = models.ManyToManyField(
43 | FileType, related_name="files")
44 |
45 | def __str__(self):
46 | return self.category
47 |
48 |
49 | class Applicants(models.Model):
50 | user = models.ForeignKey(User, on_delete=models.CASCADE)
51 | job = models.ForeignKey(
52 | Jobs, on_delete=models.CASCADE, related_name="jobs")
53 | documents = models.ManyToManyField(Documents, related_name="documents")
54 |
55 | def __str__(self):
56 | return self.user.username
57 |
--------------------------------------------------------------------------------
/task/views.py:
--------------------------------------------------------------------------------
1 | import time
2 | from openpyxl import Workbook
3 | from openpyxl.writer.excel import save_virtual_workbook
4 | from django.http import HttpResponse
5 | # Create your views here.
6 | from django.views.generic.base import TemplateView
7 | import concurrent.futures
8 | from task.models import Applicants
9 |
10 |
11 | class ExcelPageView(TemplateView):
12 | template_name = "excel_page.html"
13 |
14 |
15 | def ExportThread(app_data, sheet, row_num):
16 | for app in app_data:
17 | row_num += 1
18 | row = [
19 | app['id'],
20 | app['job__title'],
21 | app['job__category__title'],
22 | app['user__username'],
23 | app['documents__category'],
24 | app['documents__file__type']
25 | ]
26 |
27 | for col_num, cell_value in enumerate(row, 1):
28 | cell = sheet.cell(row=row_num, column=col_num)
29 | cell.value = str(cell_value)
30 |
31 |
32 | def ExportExcelfile(request):
33 |
34 | queryset = Applicants.objects.values(
35 | 'id', 'job__title', 'job__category__title', 'user__username', 'documents__category', 'documents__file__type')
36 |
37 | wb = Workbook()
38 | wb.title = "Database data"
39 | sheet = wb.active
40 |
41 | columns = ['id', 'Job', 'Job Category',
42 | 'Applicant', 'Document', 'file']
43 |
44 | for col_num, column_title in enumerate(columns, 1):
45 | cell = sheet.cell(row=1, column=col_num)
46 | cell.value = column_title
47 |
48 | # no of threads
49 | n_workers = 2
50 |
51 | chunksize = int((len(queryset) / n_workers))
52 |
53 | # starttime
54 | start = time.time()
55 | with concurrent.futures.ThreadPoolExecutor(n_workers) as executor:
56 | # split operations into chunks
57 | for i in range(1, len(queryset), chunksize):
58 | row_num = i
59 | # select a chunk
60 | app_data = queryset[i:(i + chunksize)]
61 | # submit the batch
62 | k = executor.map(
63 | ExportThread(app_data, sheet, row_num))
64 |
65 | # endtime
66 | end = time.time()
67 | # totaltime
68 | print(f'Total time to run: {end - start:2f}s')
69 | response = HttpResponse(content=save_virtual_workbook(
70 | wb), content_type='application/ms-excel')
71 | response['Content-Disposition'] = 'attachment; filename=exportedfile.xlsx'
72 | wb.save(response)
73 | return response
74 |
--------------------------------------------------------------------------------
/config/settings/base.py:
--------------------------------------------------------------------------------
1 | """
2 | Django settings for config project.
3 |
4 | Generated by 'django-admin startproject' using Django 4.1.2.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/4.1/topics/settings/
8 |
9 | For the full list of settings and their values, see
10 | https://docs.djangoproject.com/en/4.1/ref/settings/
11 | """
12 | import os
13 | from pathlib import Path
14 |
15 | # Build paths inside the project like this: BASE_DIR / 'subdir'.
16 | PROJECT_DIR = os.path.dirname(os.path.dirname(
17 | os.path.dirname(os.path.abspath(__file__))))
18 |
19 | ROOT_DIR = os.path.dirname(PROJECT_DIR)
20 |
21 | BASE_DIR = os.path.join(PROJECT_DIR, 'config')
22 |
23 | # Quick-start development settings - unsuitable for production
24 | # See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/
25 |
26 |
27 | # Application definition
28 |
29 | INSTALLED_APPS = [
30 | "django.contrib.admin",
31 | "django.contrib.auth",
32 | "django.contrib.contenttypes",
33 | "django.contrib.sessions",
34 | "django.contrib.messages",
35 | "django.contrib.staticfiles",
36 | 'task',
37 | ]
38 |
39 | MIDDLEWARE = [
40 | "django.middleware.security.SecurityMiddleware",
41 | "django.contrib.sessions.middleware.SessionMiddleware",
42 | "django.middleware.common.CommonMiddleware",
43 | "django.middleware.csrf.CsrfViewMiddleware",
44 | "django.contrib.auth.middleware.AuthenticationMiddleware",
45 | "django.contrib.messages.middleware.MessageMiddleware",
46 | "django.middleware.clickjacking.XFrameOptionsMiddleware",
47 | ]
48 |
49 | ROOT_URLCONF = "config.urls"
50 |
51 | TEMPLATES = [
52 | {
53 | "BACKEND": "django.template.backends.django.DjangoTemplates",
54 | "DIRS": [],
55 | "APP_DIRS": True,
56 | "OPTIONS": {
57 | "context_processors": [
58 | "django.template.context_processors.debug",
59 | "django.template.context_processors.request",
60 | "django.contrib.auth.context_processors.auth",
61 | "django.contrib.messages.context_processors.messages",
62 | ],
63 | },
64 | },
65 | ]
66 |
67 | WSGI_APPLICATION = "config.wsgi.application"
68 |
69 |
70 | # Password validation
71 | # https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators
72 |
73 | AUTH_PASSWORD_VALIDATORS = [
74 | {
75 | "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
76 | },
77 | {
78 | "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
79 | },
80 | {
81 | "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
82 | },
83 | {
84 | "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
85 | },
86 | ]
87 |
88 |
89 | # Internationalization
90 | # https://docs.djangoproject.com/en/4.1/topics/i18n/
91 |
92 | LANGUAGE_CODE = "en-us"
93 |
94 | TIME_ZONE = "UTC"
95 |
96 | USE_I18N = True
97 |
98 | USE_TZ = True
99 |
100 |
101 | # Static files (CSS, JavaScript, Images)
102 | # https://docs.djangoproject.com/en/4.1/howto/static-files/
103 |
104 | STATIC_URL = '/static/'
105 | STATIC_ROOT = os.path.join(ROOT_DIR, "static")
106 |
107 |
108 | MEDIA_ROOT = os.path.join(ROOT_DIR, 'media')
109 | MEDIA_URL = '/media/'
110 |
111 |
112 | # Default primary key field type
113 | # https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field
114 |
115 | DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
116 |
--------------------------------------------------------------------------------
/task/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 4.1.2 on 2022-10-17 05:33
2 |
3 | from django.conf import settings
4 | from django.db import migrations, models
5 | import django.db.models.deletion
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | initial = True
11 |
12 | dependencies = [
13 | migrations.swappable_dependency(settings.AUTH_USER_MODEL),
14 | ]
15 |
16 | operations = [
17 | migrations.CreateModel(
18 | name="FileType",
19 | fields=[
20 | (
21 | "id",
22 | models.BigAutoField(
23 | auto_created=True,
24 | primary_key=True,
25 | serialize=False,
26 | verbose_name="ID",
27 | ),
28 | ),
29 | ("type", models.FileField(upload_to="documents")),
30 | ],
31 | ),
32 | migrations.CreateModel(
33 | name="JobsCategory",
34 | fields=[
35 | (
36 | "id",
37 | models.BigAutoField(
38 | auto_created=True,
39 | primary_key=True,
40 | serialize=False,
41 | verbose_name="ID",
42 | ),
43 | ),
44 | ("title", models.CharField(max_length=300)),
45 | ],
46 | ),
47 | migrations.CreateModel(
48 | name="Jobs",
49 | fields=[
50 | (
51 | "id",
52 | models.BigAutoField(
53 | auto_created=True,
54 | primary_key=True,
55 | serialize=False,
56 | verbose_name="ID",
57 | ),
58 | ),
59 | ("title", models.CharField(max_length=300)),
60 | ("location", models.CharField(max_length=150)),
61 | (
62 | "type",
63 | models.CharField(
64 | choices=[
65 | ("Fulll time", "Full time"),
66 | ("Part time", "Part time"),
67 | ("Internship", "Internship"),
68 | ],
69 | max_length=10,
70 | ),
71 | ),
72 | ("company_name", models.CharField(max_length=100)),
73 | ("salary", models.IntegerField(blank=True, default=0)),
74 | (
75 | "category",
76 | models.ForeignKey(
77 | on_delete=django.db.models.deletion.CASCADE,
78 | to="task.jobscategory",
79 | ),
80 | ),
81 | (
82 | "user",
83 | models.ForeignKey(
84 | on_delete=django.db.models.deletion.CASCADE,
85 | to=settings.AUTH_USER_MODEL,
86 | ),
87 | ),
88 | ],
89 | ),
90 | migrations.CreateModel(
91 | name="Documents",
92 | fields=[
93 | (
94 | "id",
95 | models.BigAutoField(
96 | auto_created=True,
97 | primary_key=True,
98 | serialize=False,
99 | verbose_name="ID",
100 | ),
101 | ),
102 | (
103 | "category",
104 | models.CharField(
105 | choices=[
106 | ("Citizenship", "Citizenship"),
107 | ("passport", "passport"),
108 | ("cv", "cv"),
109 | ],
110 | max_length=255,
111 | ),
112 | ),
113 | (
114 | "file",
115 | models.ManyToManyField(related_name="files", to="task.filetype"),
116 | ),
117 | ],
118 | ),
119 | migrations.CreateModel(
120 | name="Applicants",
121 | fields=[
122 | (
123 | "id",
124 | models.BigAutoField(
125 | auto_created=True,
126 | primary_key=True,
127 | serialize=False,
128 | verbose_name="ID",
129 | ),
130 | ),
131 | (
132 | "documents",
133 | models.ManyToManyField(
134 | related_name="documents", to="task.documents"
135 | ),
136 | ),
137 | (
138 | "job",
139 | models.ForeignKey(
140 | on_delete=django.db.models.deletion.CASCADE,
141 | related_name="jobs",
142 | to="task.jobs",
143 | ),
144 | ),
145 | (
146 | "user",
147 | models.ForeignKey(
148 | on_delete=django.db.models.deletion.CASCADE,
149 | to=settings.AUTH_USER_MODEL,
150 | ),
151 | ),
152 | ],
153 | ),
154 | ]
155 |
--------------------------------------------------------------------------------