summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--workshop_app/admin.py45
-rw-r--r--workshop_app/models.py36
-rw-r--r--workshop_app/static/workshop_app/css/base.css3
-rw-r--r--workshop_app/templates/workshop_app/base.html22
4 files changed, 79 insertions, 27 deletions
diff --git a/workshop_app/admin.py b/workshop_app/admin.py
index 988351f..d236c39 100644
--- a/workshop_app/admin.py
+++ b/workshop_app/admin.py
@@ -1,4 +1,4 @@
-import csv
+import pandas as pd
from django.contrib import admin
from django.http import HttpResponse
@@ -23,21 +23,15 @@ class ProfileAdmin(admin.ModelAdmin):
actions = ['download_csv']
def download_csv(self, request, queryset):
- openfile = string_io()
+ data = queryset.values(
+ "title", "user__first_name", "user__last_name",
+ "user__email", "institute", "location", "department",
+ "phone_number"
+ )
+ df = pd.DataFrame(data)
response = HttpResponse(content_type='text/csv')
- response['Content-Disposition'] = 'attachment;filename=profile_data.csv'
- writer = csv.writer(response)
- writer.writerow(['email_id', 'title', 'username', 'first_name', 'last_name',
- 'institute', 'location', 'department',
- 'phone_number', 'position'])
- for q in queryset:
- writer.writerow([q.user.email, q.title, q.user, q.user.first_name,
- q.user.last_name, q.institute,
- q.location, q.department, q.phone_number,
- q.position])
-
- openfile.seek(0)
- response.write(openfile.read())
+ response['Content-Disposition'] = f'attachment; filename=profile.csv'
+ output_file = df.to_csv(response, index=False)
return response
download_csv.short_description = "Download CSV file for selected stats."
@@ -49,17 +43,18 @@ class WorkshopAdmin(admin.ModelAdmin):
actions = ['download_csv']
def download_csv(self, request, queryset):
- openfile = string_io()
+ data = queryset.values(
+ "workshop_type__name", "date", "coordinator__first_name",
+ "coordinator__last_name", "instructor__first_name",
+ "instructor__last_name", "status"
+ )
+ df = pd.DataFrame(data)
+ df.status.replace(
+ [0, 1, 2], ['Pending', 'Success', 'Reject'], inplace=True
+ )
response = HttpResponse(content_type='text/csv')
- response['Content-Disposition'] = 'attachment;filename=workshop_data.csv'
- writer = csv.writer(response)
- writer.writerow(['workshop_type', 'date', 'instructor', 'coordinator', 'status'])
-
- for q in queryset:
- writer.writerow([q.title, q.date, q.instructor, q.coordinator, q.status])
-
- openfile.seek(0)
- response.write(openfile.read())
+ response['Content-Disposition'] = f'attachment; filename=workshops.csv'
+ output_file = df.to_csv(response, index=False)
return response
download_csv.short_description = "Download CSV file for selected stats."
diff --git a/workshop_app/models.py b/workshop_app/models.py
index 62d10b5..48856fd 100644
--- a/workshop_app/models.py
+++ b/workshop_app/models.py
@@ -1,5 +1,6 @@
import os
import uuid
+import pandas as pd
from django.contrib.auth.models import User
from django.core.validators import RegexValidator
@@ -44,6 +45,7 @@ source = (
)
states = (
+ ("", "---------"),
("IN-AP", "Andhra Pradesh"),
("IN-AR", "Arunachal Pradesh"),
("IN-AS", "Assam"),
@@ -85,7 +87,7 @@ states = (
def has_profile(user):
""" check if user has profile """
- return True if hasattr(user, 'profile') else False
+ return hasattr(user, 'profile')
def attachments(instance, filename):
@@ -155,6 +157,34 @@ class AttachmentFile(models.Model):
workshop_type = models.ForeignKey(WorkshopType, on_delete=models.CASCADE)
+class WorkshopManager(models.Manager):
+
+ def get_workshops_by_state(self, workshops):
+ w = workshops.values_list("coordinator__profile__state", flat=True)
+ states_map = dict(states)
+ df = pd.DataFrame(w)
+ data_states, data_counts = [], []
+ if not df.empty:
+ grouped_data = df.value_counts().to_dict()
+ for state, count in grouped_data.items():
+ state_name = state[0]
+ data_states.append(states_map[state_name])
+ data_counts.append(count)
+ return data_states, data_counts
+
+ def get_workshops_by_type(self, workshops):
+ w = workshops.values_list("workshop_type__name", flat=True)
+ df = pd.DataFrame(w)
+ data_wstypes, data_counts = [], []
+ if not df.empty:
+ grouped_data = df.value_counts().to_dict()
+ for ws, count in grouped_data.items():
+ ws_name = ws[0]
+ data_wstypes.append(ws_name)
+ data_counts.append(count)
+ return data_wstypes, data_counts
+
+
class Workshop(models.Model):
"""
Contains details of workshops
@@ -179,6 +209,8 @@ class Workshop(models.Model):
help_text="I accept the terms and conditions"
)
+ objects = WorkshopManager()
+
def __str__(self):
return f"{self.workshop_type} on {self.date} by {self.coordinator}"
@@ -187,6 +219,8 @@ class Workshop(models.Model):
return choice.get(self.status)
+
+
class Testimonial(models.Model):
"""
Contains Testimonals of Workshops
diff --git a/workshop_app/static/workshop_app/css/base.css b/workshop_app/static/workshop_app/css/base.css
index 31f8da5..e8dd4ed 100644
--- a/workshop_app/static/workshop_app/css/base.css
+++ b/workshop_app/static/workshop_app/css/base.css
@@ -2,7 +2,7 @@
* Footer Styles
*/
.navbar {
- z-index: 1000;
+ z-index: 1000;
}
.footer {
position: fixed;
@@ -11,6 +11,7 @@
background-color: #61615F;
color: white;
text-align: center;
+ z-index: 100;
}
.base-content {
padding-top: 5em;
diff --git a/workshop_app/templates/workshop_app/base.html b/workshop_app/templates/workshop_app/base.html
index 7535f6a..ba968ba 100644
--- a/workshop_app/templates/workshop_app/base.html
+++ b/workshop_app/templates/workshop_app/base.html
@@ -14,6 +14,8 @@
<script src="{% static 'workshop_app/js/bootstrap.min.js' %}"></script>
<script src="{% static 'workshop_app/js/popper.min.js' %}"></script>
<script src="{% static 'workshop_app/js/toastr.min.js' %}"></script>
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
{% block extra-dependencies %}
@@ -24,6 +26,7 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet" href="{% static 'workshop_app/css/base.css' %}" type="text/css"/>
<link rel="stylesheet" href="{% static 'workshop_app/css/font-awesome.css' %}" type="text/css"/>
+ <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css">
{% block extra-custom-scripts %}
{% endblock %}
@@ -43,8 +46,27 @@
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
+ <ul class="navbar-nav">
+ <li class="nav-item">
+ <a class="nav-link text-white" href="/">
+ Home
+ </a>
+ </li>
+ <li class="nav-item">
+ <a class="nav-link text-white" href="{% url 'statistics_app:public' %}">
+ Workshop Statistics
+ </a>
+ </li>
+ </ul>
{% if user.is_authenticated %}
<ul class="navbar-nav mr-auto">
+ {% if request.user|has_group:"instructor" %}
+ <li class="nav-item">
+ <a class="nav-link text-white" href="{% url 'statistics_app:team' %}">
+ Team Statistics
+ </a>
+ </li>
+ {% endif %}
<li class="nav-item">
<a class="nav-link text-white" href="{% url 'workshop_app:workshop_status_instructor' %}">
Workshop Status