diff options
author | adityacp | 2020-08-13 16:47:59 +0530 |
---|---|---|
committer | adityacp | 2020-08-13 16:47:59 +0530 |
commit | 8e7c9aeadcae850155e17a0323b1079e0e642010 (patch) | |
tree | fff37fa8e39cae65de20ffb62358db7f3168871b | |
parent | 3e970943db3385eab32bdbc7f85fb69cf4450552 (diff) | |
download | workshop_booking-8e7c9aeadcae850155e17a0323b1079e0e642010.tar.gz workshop_booking-8e7c9aeadcae850155e17a0323b1079e0e642010.tar.bz2 workshop_booking-8e7c9aeadcae850155e17a0323b1079e0e642010.zip |
Multiple Changes
- Fix admin csv download for profile and workshops
- Add model manager to get workshops by state and type
- Add chartjs, jquery-ui in base.html
-rw-r--r-- | workshop_app/admin.py | 45 | ||||
-rw-r--r-- | workshop_app/models.py | 36 | ||||
-rw-r--r-- | workshop_app/static/workshop_app/css/base.css | 3 | ||||
-rw-r--r-- | workshop_app/templates/workshop_app/base.html | 22 |
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 |