Commit 51d22c43 authored by LiniEisha's avatar LiniEisha

Merge branch 'QA_RELEASE' into IT17100908

parents d47a2289 865e853d
import numpy as np
import os
import cv2
import getpass
import time
from datetime import datetime
filename = 'video.avi'
frames_per_second = 24.0
res = '720p'
# Set resolution for the video capture
# Function adapted from https://kirr.co/0l6qmh
def change_res(cap, width, height):
cap.set(3, width)
cap.set(4, height)
# Standard Video Dimensions Sizes
STD_DIMENSIONS = {
"480p": (640, 480),
"720p": (1280, 720),
"1080p": (1920, 1080),
"4k": (3840, 2160),
}
# grab resolution dimensions and set video capture to it.
def get_dims(cap, res='1080p'):
width, height = STD_DIMENSIONS["480p"]
if res in STD_DIMENSIONS:
width,height = STD_DIMENSIONS[res]
## change the current caputre device
## to the resulting resolution
change_res(cap, width, height)
return width, height
# Video Encoding, might require additional installs
# Types of Codes: http://www.fourcc.org/codecs.php
VIDEO_TYPE = {
'avi': cv2.VideoWriter_fourcc(*'XVID'),
#'mp4': cv2.VideoWriter_fourcc(*'H264'),
'mp4': cv2.VideoWriter_fourcc(*'XVID'),
}
def get_video_type(filename):
filename, ext = os.path.splitext(filename)
if ext in VIDEO_TYPE:
return VIDEO_TYPE[ext]
return VIDEO_TYPE['avi']
def initiate():
cap = cv2.VideoCapture(0)
out = cv2.VideoWriter(filename, get_video_type(filename), 25, get_dims(cap, res))
while True:
ret, frame = cap.read()
out.write(frame)
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
out.release()
cv2.destroyAllWindows()
\ No newline at end of file
{% extends 'FirstApp/template.html' %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% block javascript %}
{% load static %}
<!-- Bootstrap core JavaScript-->
<script src="{% static 'FirstApp/vendor/jquery/jquery.min.js' %}"></script>
<script src="{% static 'FirstApp/vendor/bootstrap/js/bootstrap.bundle.min.js' %}"></script>
<!-- Page level plugins -->
<script src="{% static 'FirstApp/vendor/datatables/jquery.dataTables.min.js' %}"></script>
<script src="{% static 'FirstApp/vendor/datatables/dataTables.bootstrap4.min.js' %}"></script>
<!-- Page level custom scripts -->
<script src="{% static 'FirstApp/js/demo/datatables-demo.js' %}"></script>
<!-- Core plugin JavaScript-->
<script src="{% static 'FirstApp/vendor/jquery-easing/jquery.easing.min.js' %}"></script>
<!-- Load TensorFlow.js -->
<script src="https://unpkg.com/@tensorflow/tfjs"></script>
<!-- Load Posenet -->
<script src="https://unpkg.com/@tensorflow-models/posenet">
</script>
<script type="text/javascript">
$(document).ready(function() {
$('#initiate_btn').click(function() {
fetch('http://127.0.0.1:8000/attendance/process-initiate-lecture')
.then((res) => res.json())
.then((out) => alert(out.response))
.catch((err) => alert('error: ' + err))
});
})
</script>
{% endblock %}
{% block 'container-fluid' %}
<div class="container">
<div class="row p-4">
<div class="col-lg-12">
<div class="text-center">
<div class="card">
<div class="card-header">
<h4 class="card-title">Starting the lecture....</h4>
</div>
<div class="card-body">
<button type="button" class="btn btn-success" id="initiate_btn">Initiate Lecture</button>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
</body>
</html>
\ No newline at end of file
...@@ -4,23 +4,67 @@ from rest_framework.response import Response ...@@ -4,23 +4,67 @@ from rest_framework.response import Response
from LectureSummarizingApp.models import LectureAudioSummary from LectureSummarizingApp.models import LectureAudioSummary
from LectureSummarizingApp.serializer import LectureAudioSummarySerializer from LectureSummarizingApp.serializer import LectureAudioSummarySerializer
from . logic import classroom_activity, text_analysis as ta from . logic import classroom_activity, text_analysis as ta
from .models import LecturerVideo, LecturerAudioText from .models import LecturerVideo, LecturerAudioText, LecturerVideoMetaData, LectureRecordedVideo
from .serializers import LecturerVideoSerializer, LecturerAudioTextSerializer from .serializers import *
import datetime import datetime
##### LECTURER ACTIVITY SECTION #####
class ActivityRecognitionAPI(APIView): class ActivityRecognitionAPI(APIView):
def get(self, request): def get(self, request):
video_name = request.query_params.get('video_name') video_name = request.query_params.get('video_name')
# retrieve the lecturer video details with the video name
lec_video = LectureRecordedVideo.objects.filter(lecture_video_name=video_name)
lec_video_ser = LectureRecordedVideoSerializer(lec_video, many=True)
lec_video_data = lec_video_ser.data
percentages = classroom_activity.activity_recognition(video_name) percentages = classroom_activity.activity_recognition(video_name)
# saving to the db
LecturerVideoMetaData(
lecturer_video_id_id=lec_video_data[0]['id'],
seated_count=percentages["sitting_perct"],
standing_count=percentages["standing_perct"],
walking_count=percentages["walking_perct"]
).save()
return Response({"response": percentages}) return Response({"response": percentages})
def post(self, request): def post(self, request):
pass pass
# this method will retrieve the lecturer video meta data results
class GetLectureVideoResultsAPI(APIView):
def get(self, request):
video_id = request.query_params.get('video_id')
int_video_id = int(video_id)
# retrieve from the db
video_meta_data = LecturerVideoMetaData.objects.filter(lecturer_video_id_id=int_video_id)
video_meta_data_ser = LecturerVideoMetaDataSerializer(video_meta_data, many=True)
video_meta_data_processed = video_meta_data_ser.data
percentages = {}
for meta_data in video_meta_data_processed:
percentages["sitting_perct"] = meta_data["seated_count"]
percentages["standing_perct"] = meta_data["standing_count"]
percentages["walking_perct"] = meta_data["walking_count"]
return Response({
"response": percentages
})
##### END OF LECTURER ACTIVITY SECTION #####
# class ActivityRecognitionAPI(APIView): # class ActivityRecognitionAPI(APIView):
# #
# def get(self, request): # def get(self, request):
...@@ -39,11 +83,17 @@ class GetLectureAudioAnalysis(APIView): ...@@ -39,11 +83,17 @@ class GetLectureAudioAnalysis(APIView):
lec_audio_id = request.query_params.get("audio_id") lec_audio_id = request.query_params.get("audio_id")
int_audio_id = int(lec_audio_id) int_audio_id = int(lec_audio_id)
print('audio id: ', int_audio_id)
# all_lec_audio_summary
lec_audio_summary = LectureAudioSummary.objects.filter(lecture_audio_id=int_audio_id) lec_audio_summary = LectureAudioSummary.objects.filter(lecture_audio_id=int_audio_id)
lec_audio_summary_serializer = LectureAudioSummarySerializer(lec_audio_summary, many=True) lec_audio_summary_serializer = LectureAudioSummarySerializer(lec_audio_summary, many=True)
audio_summary_data = lec_audio_summary_serializer.data audio_summary_data = lec_audio_summary_serializer.data
lec_audio_summary_id = 0 lec_audio_summary_id = 0
print('lec audio summary: ', len(audio_summary_data))
for audio in audio_summary_data: for audio in audio_summary_data:
lec_audio_summary_id = audio['id'] lec_audio_summary_id = audio['id']
...@@ -52,6 +102,7 @@ class GetLectureAudioAnalysis(APIView): ...@@ -52,6 +102,7 @@ class GetLectureAudioAnalysis(APIView):
lec_audio_text_serializer = LecturerAudioTextSerializer(lec_audio_text, many=True) lec_audio_text_serializer = LecturerAudioTextSerializer(lec_audio_text, many=True)
lec_audio_text_data = lec_audio_text_serializer.data lec_audio_text_data = lec_audio_text_serializer.data
print('lec audio text data: ', len(lec_audio_text_data))
audio_text = [] audio_text = []
...@@ -157,3 +208,5 @@ class LecturerAudioSummaryPeriodAPI(APIView): ...@@ -157,3 +208,5 @@ class LecturerAudioSummaryPeriodAPI(APIView):
"labels": labels, "labels": labels,
"isRecordFound": isRecordFound "isRecordFound": isRecordFound
}) })
...@@ -15,12 +15,9 @@ def activity_recognition(video_name): ...@@ -15,12 +15,9 @@ def activity_recognition(video_name):
# detector_path = os.path.join(CLASSIFIER_DIR, "keras_model.h5") # detector_path = os.path.join(CLASSIFIER_DIR, "keras_model.h5")
detector_path = os.path.join(CLASSIFIER_DIR, "keras_model_updated.h5") detector_path = os.path.join(CLASSIFIER_DIR, "keras_model_updated.h5")
# Disable scientific notation for clarity # Disable scientific notation for clarity
np.set_printoptions(suppress=True) np.set_printoptions(suppress=True)
...@@ -36,20 +33,15 @@ def activity_recognition(video_name): ...@@ -36,20 +33,15 @@ def activity_recognition(video_name):
metrics=['accuracy']) metrics=['accuracy'])
# Create the array of the right shape to feed into the keras model # Create the array of the right shape to feed into the keras model
# The 'length' or number of images you can put into the array is # The 'length' or number of images you can put into the array is
# determined by the first position in the shape tuple, in this case 1. # determined by the first position in the shape tuple, in this case 1.
data = np.ndarray(shape=(1, 224, 224, 3), dtype=np.float32) data = np.ndarray(shape=(1, 224, 224, 3), dtype=np.float32)
size = (224, 224) size = (224, 224)
# "C://Users//DELL//Downloads//Classroom_Video.mp4" # "C://Users//DELL//Downloads//Classroom_Video.mp4"
video1 = 'E:\\Studies\\SLIIT\\4th Year\\Python Projects\\classroom activity models\\videos\\{}'.format(video_name) video1 = 'E:\\Studies\\SLIIT\\4th Year\\Python Projects\\classroom activity models\\videos\\{}'.format(video_name)
video = cv2.VideoCapture(VIDEO_PATH) video = cv2.VideoCapture(VIDEO_PATH)
# additional # additional
# getting the frames per second (fps) # getting the frames per second (fps)
# fps = video.get(cv2.CAP_PROP_FPS) # fps = video.get(cv2.CAP_PROP_FPS)
......
...@@ -46,7 +46,7 @@ def run(): ...@@ -46,7 +46,7 @@ def run():
else: else:
d[word] = 1 d[word] = 1
# the key words are "extraneous filler words (ok, well, like, Actually, Basically, that, jest, only, really, very, now, simply, maybe, perhaps, somehow, almost, slightly, seemed ....)" # the key words are "extraneous filler words (ok, well, like, Actually, Basically, that, jest, only, really, very, now, simply, maybe, perhaps, somehow, almost, slightly, seemed ....)"
for key in list(d.keys()): for key in list(d.keys()):
if (key == "like"): if (key == "like"):
......
# Generated by Django 2.2.11 on 2020-09-30 04:41
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('MonitorLecturerApp', '0003_auto_20200915_1449'),
]
operations = [
migrations.AddField(
model_name='lecturervideometadata',
name='lecturer_video_id',
field=models.ForeignKey(default=0, on_delete=django.db.models.deletion.CASCADE, to='MonitorLecturerApp.LectureRecordedVideo'),
),
]
...@@ -29,7 +29,21 @@ class LecturerVideo(models.Model): ...@@ -29,7 +29,21 @@ class LecturerVideo(models.Model):
return self.name return self.name
class LectureRecordedVideo (models.Model):
lecture_video_id = models.CharField(max_length=10)
lecturer_date = models.DateField()
lecture_video_name = models.CharField(max_length=50)
lecture_video_length = models.DurationField()
lecturer = models.ForeignKey(Lecturer, on_delete=models.CASCADE, default=0)
subject = models.ForeignKey(Subject, on_delete=models.CASCADE, default=0)
def __str__(self):
return self.lecture_video_id
class LecturerVideoMetaData(models.Model): class LecturerVideoMetaData(models.Model):
lecturer_video_id = models.ForeignKey(LectureRecordedVideo, on_delete=models.CASCADE, default=0)
fps = models.IntegerField() fps = models.IntegerField()
frame_count = models.IntegerField() frame_count = models.IntegerField()
seated_count = models.IntegerField() seated_count = models.IntegerField()
...@@ -73,13 +87,3 @@ class LecturerAudioText (models.Model): ...@@ -73,13 +87,3 @@ class LecturerAudioText (models.Model):
def __str__(self): def __str__(self):
return self.lecturer_audio_text_id return self.lecturer_audio_text_id
class LectureRecordedVideo (models.Model):
lecture_video_id = models.CharField(max_length=10)
lecturer_date = models.DateField()
lecture_video_name = models.CharField(max_length=50)
lecture_video_length = models.DurationField()
lecturer = models.ForeignKey(Lecturer, on_delete=models.CASCADE, default=0)
subject = models.ForeignKey(Subject, on_delete=models.CASCADE, default=0)
def __str__(self):
return self.lecture_video_id
\ No newline at end of file
...@@ -17,11 +17,6 @@ class LecturerVideoSerializer(serializers.ModelSerializer): ...@@ -17,11 +17,6 @@ class LecturerVideoSerializer(serializers.ModelSerializer):
model = LecturerVideo model = LecturerVideo
fields = '__all__' fields = '__all__'
class LecturerVideoMetaDataSerializer(serializers.ModelSerializer):
class Meta:
model = LecturerVideoMetaData
fields = '__all__'
class LecturerAudioTextSerializer(serializers.ModelSerializer): class LecturerAudioTextSerializer(serializers.ModelSerializer):
...@@ -40,3 +35,12 @@ class LectureRecordedVideoSerializer(serializers.ModelSerializer): ...@@ -40,3 +35,12 @@ class LectureRecordedVideoSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = LectureRecordedVideo model = LectureRecordedVideo
fields = '__all__' fields = '__all__'
class LecturerVideoMetaDataSerializer(serializers.ModelSerializer):
lecturer_video_id = LectureRecordedVideoSerializer()
class Meta:
model = LecturerVideoMetaData
fields = '__all__'
\ No newline at end of file
...@@ -39,29 +39,58 @@ ...@@ -39,29 +39,58 @@
var lecture_audio_text_summary = {}; var lecture_audio_text_summary = {};
$(document).ready(function () { $(document).ready(function () {
$('.calc').click(function () { $('.calc').click(function (e) {
let video_name = $(this).attr('id'); let video_name = $(this).attr('data-name');
$('#loader').attr('hidden', false); $('#no_content_message').attr('hidden', true);
$('#video_loader').attr('hidden', false);
// alert('hello'); // alert('hello');
$('#no_content_message').attr('hidden', true);
//fetching data from the API //fetching data from the API
fetch('http://127.0.0.1:8000/lecturer/activities/?video_name=' + video_name) fetch('http://127.0.0.1:8000/lecturer/activities/?video_name=' + video_name)
.then((res) => res.json()) .then((res) => res.json())
.then((out) => assignPerct(out.response)) .then((out) => assignPerct(out.response, e))
.catch((error) => alert('error ' + error)) .catch((error) => alert('error ' + error));
}); });
//this function will handle the lecturer video results button
$('.results').click(function (e) {
let video_id = $(this).attr('data-id');
$('#no_content_message').attr('hidden', true);
$('#video_loader').attr('hidden', false);
//fetch the results
fetch('http://127.0.0.1:8000/lecturer/get-lecturer-video-results/?video_id=' + video_id)
.then((res) => res.json())
.then((out) => assignPerct(out.response, e))
.catch((err) => alert('error: ' + err))
});
//to assign percentage values //to assign percentage values
function assignPerct(percentages) { function assignPerct(percentages, e) {
$('#no_content_message').attr('hidden', true); $('#no_content_message').attr('hidden', true);
$('#progress_bars').attr('hidden', false); $('#progress_bars').attr('hidden', false);
$('#loader').attr('hidden', true); $('#loader').attr('hidden', true);
//display the 'results' button
{#e.target.parentNode.innerHTML = "<span class='font-italic bg-success'>Processed</span>";#}
{#alert("Result button error");#}
{#let sitting = Math.round(percentages.sitting_perct);#} {#let sitting = Math.round(percentages.sitting_perct);#}
let sitting = Math.round(percentages.sitting_perct); let sitting = Math.round(percentages.sitting_perct);
let standing = Math.round(percentages.standing_perct); let standing = Math.round(percentages.standing_perct);
...@@ -75,9 +104,10 @@ ...@@ -75,9 +104,10 @@
$('#standing_span').text(standing + '%'); $('#standing_span').text(standing + '%');
$('#walking_span').text(walking + '%'); $('#walking_span').text(walking + '%');
$('#video_loader').hide();
} }
/* /*
//this is for the temporay button (delete later) //this is for the temporay button (delete later)
$('#temp_btn').click(function () { $('#temp_btn').click(function () {
...@@ -443,8 +473,8 @@ ...@@ -443,8 +473,8 @@
<!-- Card Header - Dropdown --> <!-- Card Header - Dropdown -->
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between"> <div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
<h6 class="m-0 font-weight-bold text-primary">Video List</h6> <h6 class="m-0 font-weight-bold text-primary">Video List</h6>
{# <button type="button" class="btn btn-outline-primary" id="video_graph">Statistics#} <button type="button" class="btn btn-outline-primary" id="video_graph">Statistics
{# </button>#} </button>
</div> </div>
<!-- Card Body --> <!-- Card Body -->
...@@ -463,11 +493,21 @@ ...@@ -463,11 +493,21 @@
<tr> <tr>
<td>{{ video.name }}</td> <td>{{ video.name }}</td>
<td>{{ video.duration }}</td> <td>{{ video.duration }}</td>
<td class="btn_class"> {% if video.isAvailable %}
<td class="btn_class">
<button type="button" class="btn btn-primary results"
data-name='{{ video.name }}'
data-id="{{ video.video_id }}">Results
</button>
</td>
{% else %}
<td class="btn_class">
<button type="button" class="btn btn-success calc" <button type="button" class="btn btn-success calc"
id='{{ video.name }}'>Calculate data-name='{{ video.name }}'>Calculate
</button> </button>
</td> </td>
{% endif %}
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
...@@ -498,7 +538,6 @@ ...@@ -498,7 +538,6 @@
<!--loader --> <!--loader -->
<div class="text-center" id="audio_loader" hidden> <div class="text-center" id="audio_loader" hidden>
{# <img src="{% static 'FirstApp/images/ajax-loader.gif' %}" alt="">#}
<img src="{% static 'FirstApp/images/ajax-loader.gif' %}" alt=""> <img src="{% static 'FirstApp/images/ajax-loader.gif' %}" alt="">
...@@ -515,22 +554,15 @@ ...@@ -515,22 +554,15 @@
<!-- table body--> <!-- table body-->
<tbody> <tbody>
<tr> <tr>
<td>No of Total words</td> <td>No of Total words: </td>
<td id="num_of_words"></td> <td id="num_of_words"></td>
</tr> </tr>
<tr> <tr>
<td>No fo word to be expected</td> <td>No of word expected: </td>
<td> 3600 - 4800</td> <td> 3600 - 4800</td>
</tr> </tr>
{# <tr>#}
{# <td>No of extraneous words</td>#}
{# <td id="lexical_count"></td>#}
{# </tr>#}
{# <tr>#}
{# <td>No of Non-lexical words</td>#}
{# <td id="non_lexical_count"></td>#}
{# </tr>#}
</tbody> </tbody>
</table> </table>
<!--button --> <!--button -->
...@@ -676,11 +708,11 @@ ...@@ -676,11 +708,11 @@
<table class="table table-borderless"> <table class="table table-borderless">
<tbody> <tbody>
<tr> <tr>
<td>No. of extraneous words</td> <td>No. of extraneous words: </td>
<td id="lexical_count"></td> <td id="lexical_count"></td>
</tr> </tr>
<tr> <tr>
<td>No. of non-lexical words</td> <td>No. of non-lexical words: </td>
<td id="non_lexical_count"></td> <td id="non_lexical_count"></td>
</tr> </tr>
</tbody> </tbody>
......
...@@ -24,9 +24,16 @@ urlpatterns = [ ...@@ -24,9 +24,16 @@ urlpatterns = [
path('lecture-video', views.lecVideo), path('lecture-video', views.lecVideo),
# path('Video', views.hello) # path('Video', views.hello)
##### LECTURER ACTIVITY SECTION #####
# API to retrieve activity recognition # API to retrieve activity recognition
url(r'^activities/$', api.ActivityRecognitionAPI.as_view()), url(r'^activities/$', api.ActivityRecognitionAPI.as_view()),
# API to retrieve lecturer video meta data results
url(r'^get-lecturer-video-results/$', api.GetLectureVideoResultsAPI.as_view()),
##### END OF LECTURER ACTIVITY SECTION #####
# API to retrieve audio analysis # API to retrieve audio analysis
url(r'^get-audio-analysis/$', api.GetLectureAudioAnalysis.as_view()), url(r'^get-audio-analysis/$', api.GetLectureAudioAnalysis.as_view()),
......
...@@ -8,8 +8,8 @@ from rest_framework.response import Response ...@@ -8,8 +8,8 @@ from rest_framework.response import Response
from LectureSummarizingApp.models import LectureAudio from LectureSummarizingApp.models import LectureAudio
from LectureSummarizingApp.serializer import LectureAudioSerializer from LectureSummarizingApp.serializer import LectureAudioSerializer
from . import views from . import views
from .models import RegisterTeacher, LecturerVideo from .models import *
from . serializers import RegisterTeacherSerializer from . serializers import *
import cv2 import cv2
import os import os
...@@ -70,8 +70,14 @@ def hello(request): ...@@ -70,8 +70,14 @@ def hello(request):
# the list needs to be sorted by the date # the list needs to be sorted by the date
lec_list.sort(key=lambda date: dt.strptime(str(date['date']), "%Y-%m-%d"), reverse=True) lec_list.sort(key=lambda date: dt.strptime(str(date['date']), "%Y-%m-%d"), reverse=True)
# retrieve exsiting lecture recorded videos
lec_video_meta = LecturerVideoMetaData.objects.all()
lec_video_meta_ser = LecturerVideoMetaDataSerializer(lec_video_meta, many=True)
lec_video_meta_data = lec_video_meta_ser.data
for videoPath in videoPaths: for videoPath in videoPaths:
video = LecturerVideo() video = LecturerVideo()
video = {}
cap = cv2.VideoCapture(videoPath) cap = cv2.VideoCapture(videoPath)
fps = cap.get(cv2.CAP_PROP_FPS) # OpenCV2 version 2 used "CV_CAP_PROP_FPS" fps = cap.get(cv2.CAP_PROP_FPS) # OpenCV2 version 2 used "CV_CAP_PROP_FPS"
frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
...@@ -80,11 +86,23 @@ def hello(request): ...@@ -80,11 +86,23 @@ def hello(request):
videoName = os.path.basename(videoPath) videoName = os.path.basename(videoPath)
# videoName = videos.append(os.path.basename(videoPath)) # videoName = videos.append(os.path.basename(videoPath))
durationObj = datetime.timedelta(seconds=duration) durationObj = datetime.timedelta(seconds=duration)
video.path = videoPath video['path'] = videoPath
video.name = videoName video['name'] = videoName
video.duration = str(durationObj) video['duration'] = str(durationObj)
video['video_id'] = None
# checking whether this video already exists
for recorded_lecture in lec_video_meta_data:
print('recorded lecture: ', recorded_lecture)
if videoName == recorded_lecture['lecturer_video_id']['lecture_video_name']:
video['isAvailable'] = True
video['video_id'] = recorded_lecture['lecturer_video_id']['id']
videos.append(video) videos.append(video)
print('Video Name: ', video.name) print('Video Name: ', video['name'])
context = {'object': obj, 'Videos': videos, 'durations': durations, 'template_name': 'MonitorLecturerApp/template.html', 'lec_list': lec_list} context = {'object': obj, 'Videos': videos, 'durations': durations, 'template_name': 'MonitorLecturerApp/template.html', 'lec_list': lec_list}
return render(request, 'MonitorLecturerApp/index.html', context) return render(request, 'MonitorLecturerApp/index.html', context)
......
This is a sample text file
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment