Commit 753af621682a731955e3c03a5a08203ef6a0bc44
Exists in
master
and in
5 other branches
Merge branch 'dev' of https://github.com/amadeusproject/amadeuslms into dev
Showing
10 changed files
with
314 additions
and
190 deletions
Show diff stats
courses/models.py
... | ... | @@ -65,9 +65,11 @@ class Course(models.Model): |
65 | 65 | |
66 | 66 | def show_subscribe(self): |
67 | 67 | today = datetime.date.today() |
68 | - | |
69 | 68 | return today >= self.init_register_date and today <= self.end_register_date |
70 | 69 | |
70 | + def duration(self): | |
71 | + return self.end_date - self.init_date | |
72 | + | |
71 | 73 | class Subject(models.Model): |
72 | 74 | |
73 | 75 | name = models.CharField(_('Name'), max_length = 100) | ... | ... |
courses/static/js/course.js
1 | 1 | /* |
2 | 2 | * |
3 | +* Function to get a cookie stored on browser | |
4 | +* | |
5 | +*/ | |
6 | +function getCookie(name) { | |
7 | + var cookieValue = null; | |
8 | + if (document.cookie && document.cookie !== '') { | |
9 | + var cookies = document.cookie.split(';'); | |
10 | + for (var i = 0; i < cookies.length; i++) { | |
11 | + var cookie = jQuery.trim(cookies[i]); | |
12 | + // Does this cookie string begin with the name we want? | |
13 | + if (cookie.substring(0, name.length + 1) === (name + '=')) { | |
14 | + cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); | |
15 | + break; | |
16 | + } | |
17 | + } | |
18 | + } | |
19 | + return cookieValue; | |
20 | +} | |
21 | +/* | |
22 | +* | |
3 | 23 | * Function to subscribe (works for courses and subjects) |
4 | 24 | * |
5 | 25 | */ |
... | ... | @@ -19,4 +39,42 @@ function subscribe(elem, url, id, confirm_message) { |
19 | 39 | } |
20 | 40 | }); |
21 | 41 | }); |
42 | +} | |
43 | + | |
44 | +/* | |
45 | +* | |
46 | +* Function to delete a course | |
47 | +* | |
48 | +*/ | |
49 | +function delete_course(url, course, message, return_url) { | |
50 | + alertify.confirm(message, function(){ | |
51 | + var csrftoken = getCookie('csrftoken'); | |
52 | + | |
53 | + $.ajax({ | |
54 | + method: 'post', | |
55 | + beforeSend: function (request) { | |
56 | + request.setRequestHeader('X-CSRFToken', csrftoken); | |
57 | + }, | |
58 | + url: url, | |
59 | + success: function(data) { | |
60 | + alertify.alert('Remove Course', 'Course removed successfully!', function(){ | |
61 | + window.location.href = return_url; | |
62 | + }); | |
63 | + } | |
64 | + }); | |
65 | + }); | |
66 | +} | |
67 | +/* | |
68 | +* | |
69 | +* Function to load create course's form | |
70 | +* | |
71 | +*/ | |
72 | +function replicate_course(url, course) { | |
73 | + $.ajax({ | |
74 | + url: url, | |
75 | + data: {'form': course}, | |
76 | + success: function(data) { | |
77 | + $(".course_replicate_form").html(data); | |
78 | + } | |
79 | + }); | |
22 | 80 | } |
23 | 81 | \ No newline at end of file | ... | ... |
courses/templates/category/index.html
... | ... | @@ -80,11 +80,9 @@ |
80 | 80 | <td>{{ category }}</td> |
81 | 81 | <td>{{ category.slug }}</td> |
82 | 82 | <td class="text-center"> |
83 | - <a href="{% url 'course:view_cat' category.slug %}" class="btn btn-info btn-sm"><span class="glyphicon glyphicon-eye-open"></span></a> | |
84 | - <a href="{% url 'course:update_cat' category.slug %}" class="btn btn-primary btn-sm"><span class="glyphicon glyphicon-edit"></span></a> | |
85 | - <a href="javascript:modal.get('{% url 'course:delete_cat' category.slug %}','#category','#modal_category');" class="btn btn-danger btn-sm"><span class="glyphicon glyphicon-trash"></span></a> | |
86 | - | |
87 | - </td> | |
83 | + <a href="{% url 'course:update_cat' category.slug %}" class="btn btn-primary btn-sm"><span class="glyphicon glyphicon-edit"></span></a> | |
84 | + <a href="javascript:modal.get('{% url 'course:delete_cat' category.slug %}','#category','#modal_category');" class="btn btn-danger btn-sm"><span class="glyphicon glyphicon-trash"></span></a> | |
85 | + </td> | |
88 | 86 | </tr> |
89 | 87 | {% endfor %} |
90 | 88 | {% else %} | ... | ... |
courses/templates/category/view.html
... | ... | @@ -1,69 +0,0 @@ |
1 | -{% extends 'base.html' %} | |
2 | - | |
3 | -{% load static i18n permission_tags %} | |
4 | -{% load widget_tweaks %} | |
5 | -{% load static i18n %} | |
6 | - | |
7 | - | |
8 | -{% block breadcrumbs %} | |
9 | - <ol class="breadcrumb"> | |
10 | - <li><a href="{% url 'app:index' %}">{% trans 'Home' %}</a></li> | |
11 | - <li class="active">{{ category }}</li> | |
12 | - </ol> | |
13 | -{% endblock %} | |
14 | - | |
15 | -{% block sidebar %} | |
16 | - <div class="panel panel-primary navigation"> | |
17 | - <div class="panel-heading"> | |
18 | - <h5>{% trans 'Menu' %}</h5> | |
19 | - </div> | |
20 | - <div class="panel-body"> | |
21 | - <ul class="nav nav-pills nav-stacked"> | |
22 | - <li><a href="{% url 'users:profile' %}">{% trans 'Profile' %}</a></li> | |
23 | - <li><a href="{% url 'course:manage' %}">{% trans 'My Courses' %}</a></li> | |
24 | - </ul> | |
25 | - </div> | |
26 | - </div> | |
27 | - {% if user|has_role:'professor' or user|has_role:'system_admin' %} | |
28 | - | |
29 | - <div class="panel panel-primary navigation"> | |
30 | - <div class="panel-heading"> | |
31 | - <h3 class="panel-title">Actions</h3> | |
32 | - </div> | |
33 | - <div class="panel-body"> | |
34 | - <ul class="nav nav-pills nav-stacked"> | |
35 | - <li><a href="javascript:void(0)">Replicate Course</a></li> | |
36 | - <li><a href="{% url 'course:create' %}">Create Course</a></li> | |
37 | - <li><a href="{% url 'course:create_cat' %}">Create Category</a></li> | |
38 | - </ul> | |
39 | - </div> | |
40 | - </div> | |
41 | - | |
42 | - <div class="panel panel-primary navigation"> | |
43 | - <div class="panel-heading"> | |
44 | - <h3 class="panel-title">Category</h3> | |
45 | - </div> | |
46 | - <div class="panel-body"> | |
47 | - <ul class="nav nav-pills nav-stacked"> | |
48 | - <li><a href="{% url 'course:create_cat' %}">Create Category</a></li> | |
49 | - <li><a href="{% url 'course:manage_cat' %}">List Category</a></li> | |
50 | - <li><a href="{% url 'course:delete_cat' category.slug %}">Remove Category</a></li> | |
51 | - <li><a href="{% url 'course:update_cat' category.slug %}">Update Category</a></li> | |
52 | - </ul> | |
53 | - </div> | |
54 | - </div> | |
55 | - {% endif %} | |
56 | -{% endblock %} | |
57 | - | |
58 | -{% block content %} | |
59 | - <div class="card card-content"> | |
60 | - <div class="card-body"> | |
61 | - <div class="row"> | |
62 | - <div class="col-sm-12"> | |
63 | - <p><b>{% trans 'Name:' %} </b> {{ category }}</p> | |
64 | - <p><b>{% trans 'Slug:' %} </b> {{ category.slug }}</p> | |
65 | - </div> | |
66 | - </div> | |
67 | - </div> | |
68 | - </div> | |
69 | -{% endblock %} |
courses/templates/course/course_card.html
1 | 1 | {% load static i18n permission_tags %} |
2 | 2 | {% load django_bootstrap_breadcrumbs %} |
3 | 3 | |
4 | -<div class="panel-group ui-accordion ui-widget ui-helper-reset ui-sortable" id="accordion" role="tablist" aria-multiselectable="false"> | |
5 | - <div class="group"> | |
6 | - <div class="panel panel-info"> | |
7 | - <div class="panel-heading" role="tab"> | |
8 | - <div class="row"> | |
9 | - <div class="col-xs-9 col-md-10 titleTopic"> | |
10 | - <a role="button" data-toggle="collapse" data-parent="#accordion" href=".collapseOne" aria-expanded="false" aria-controls="collapseOne" class="collapsed"> | |
11 | - <h4 style="color:white">{{course.name}}</h4> | |
12 | - </a> | |
13 | - </div> | |
14 | - {% if user|has_role:'professor' or user|has_role:'system_admin' %} | |
15 | - <div class="col-xs-4 col-md-2" id="divMoreActions"> | |
16 | - <div class="btn-group"> | |
17 | - <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> | |
18 | - <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i> | |
19 | - </button> | |
20 | - <ul class="dropdown-menu" aria-labelledby="moreActions"> | |
21 | - <li><a href="javascript:void(0)" data-toggle="modal" data-target="#myModal4"><i class="fa fa-files-o fa-fw" aria-hidden="true"></i> Replicate</a></li> | |
22 | - <li><a href="javascript:void(0)" data-toggle="modal" data-target="#removeCourse"><i class="fa fa-trash fa-fw" aria-hidden="true"></i> Remove</a></li> | |
23 | - </ul> | |
24 | - </div> | |
25 | - </div> | |
26 | - {% endif %} | |
27 | - </div> | |
28 | - </div> | |
29 | - <div class="panel-collapse collapseOne collapse in" role="tabpanel" aria-labelledby="headingOne" aria-expanded="true" aria-hidden="false" tabindex="0"> | |
30 | - <div class="panel-body"> | |
31 | - <p><b>Course Name: </b>{{course.name}}</p> | |
32 | - <p><b>Coordinator: </b>{{course.professors.all.0}}</p> | |
33 | - <p> | |
34 | - <b>Description:</b> | |
35 | - <i> | |
36 | - {{course.description}} | |
37 | - </i> | |
38 | - </p> | |
39 | - <a href="{% url 'course:view' course.slug %}" class="btn btn-raised btn-default center-block">{% trans 'View Course' %}<div class="ripple-container"></div></a> | |
40 | - </div> | |
41 | - </div> | |
42 | - </div> | |
43 | - </div> | |
44 | - </div> | |
45 | 4 | \ No newline at end of file |
5 | +<div class="panel-group ui-accordion ui-widget ui-helper-reset ui-sortable" id="accordion-{{course.slug}}" role="tablist" aria-multiselectable="false"> | |
6 | + <div class="group"> | |
7 | + <div class="panel panel-info"> | |
8 | + <div class="panel-heading" role="tab"> | |
9 | + <div class="row"> | |
10 | + <div class="col-xs-9 col-md-10 titleTopic"> | |
11 | + <a role="button" data-toggle="collapse" data-parent="#accordion-{{course.slug}}" href=".collapseOne-{{course.slug}}" aria-expanded="false" aria-controls="collapseOne-{{course.slug}}" class="collapsed"> | |
12 | + <h4 style="color:white">{{course.name}}</h4> | |
13 | + </a> | |
14 | + </div> | |
15 | + {% if user|has_role:'professor' or user|has_role:'system_admin' %} | |
16 | + <div class="col-xs-4 col-md-2" id="divMoreActions"> | |
17 | + <div class="btn-group"> | |
18 | + <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> | |
19 | + <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i> | |
20 | + </button> | |
21 | + <ul class="dropdown-menu" aria-labelledby="moreActions"> | |
22 | + <li><a href="{% url 'course:replicate_course' course.slug %}"><i class="fa fa-files-o fa-fw" aria-hidden="true"></i>{% trans 'Replicate' %}</a></li> | |
23 | + <li><a href="javascript:delete_course('{% url 'course:delete' course.slug %}', '{{ course.slug }}', '{% trans "Are you sure you want to delete this course?" %}', '{% url 'course:manage' %}')"><i class="fa fa-trash fa-fw" aria-hidden="true"></i>{% trans 'Remove' %}</a></li> | |
24 | + </ul> | |
25 | + </div> | |
26 | + </div> | |
27 | + {% endif %} | |
28 | + </div> | |
29 | + </div> | |
30 | + <div class="panel-collapse collapseOne-{{course.slug}} collapse in" role="tabpanel" aria-labelledby="headingOne" aria-expanded="true" aria-hidden="false" tabindex="0"> | |
31 | + <div class="panel-body"> | |
32 | + <p><b>Course Name: </b>{{course.name}}</p> | |
33 | + <p><b>Coordinator: </b>{{course.professors.all.0}}</p> | |
34 | + <p> | |
35 | + <b>Description:</b> | |
36 | + <i> | |
37 | + {{course.content}} | |
38 | + </i> | |
39 | + </p> | |
40 | + <a href="{% url 'course:view' course.slug %}" class="btn btn-raised btn-default center-block">{% trans 'View Course' %}<div class="ripple-container"></div></a> | |
41 | + </div> | |
42 | + </div> | |
43 | + </div> | |
44 | + </div> | |
45 | +</div> | |
46 | + | |
47 | +<div class="modal fade" id="replicateCourse" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"> | |
48 | + <div class="modal-dialog" role="document"> | |
49 | + <div class="modal-content"> | |
50 | + <div class="modal-header"> | |
51 | + <h4 class="modal-title" id="myModalLabel">{% trans 'Repicate Course' %}</h4> | |
52 | + </div> | |
53 | + <div class="modal-body"> | |
54 | + <section> | |
55 | + <div class="course_replicate_form"></div> | |
56 | + </section> | |
57 | + </div> | |
58 | + <div class="modal-footer"> | |
59 | + <button type="button" class="btn btn-danger btn-raised" data-dismiss="modal">{% trans 'Close' %}</button> | |
60 | + <button type="button" onclick="$('#course_replicate').submit();" class="btn btn-primary btn-raised">{% trans 'Create' %}</button> | |
61 | + </div> | |
62 | + </div> | |
63 | + </div> | |
64 | +</div> | |
46 | 65 | \ No newline at end of file | ... | ... |
courses/templates/course/index.html
... | ... | @@ -41,6 +41,21 @@ |
41 | 41 | </ul> |
42 | 42 | </div> |
43 | 43 | </div> |
44 | + | |
45 | + {% if user|has_role:'professor' or user|has_role:'system_admin' %} | |
46 | + | |
47 | + <div class="panel panel-primary navigation"> | |
48 | + <div class="panel-heading"> | |
49 | + <h3 class="panel-title">Category</h3> | |
50 | + </div> | |
51 | + <div class="panel-body"> | |
52 | + <ul class="nav nav-pills nav-stacked"> | |
53 | + <li><a href="{% url 'course:create_cat' %}">Create Category</a></li> | |
54 | + <li><a href="{% url 'course:manage_cat' %}">List Category</a></li> | |
55 | + </ul> | |
56 | + </div> | |
57 | + </div> | |
58 | + {% endif %} | |
44 | 59 | {% endblock %} |
45 | 60 | |
46 | 61 | {% block content %} |
... | ... | @@ -81,74 +96,13 @@ |
81 | 96 | {% for course in courses_category %} |
82 | 97 | {% if course.category.name == request.GET.category %} |
83 | 98 | <!-- Put your content here! --> |
84 | - <div class="panel-group ui-accordion ui-widget ui-helper-reset ui-sortable" id="accordion" role="tablist" aria-multiselectable="false"> | |
85 | - <div class="group"> | |
86 | - <div class="panel panel-info"> | |
87 | - <div class="panel-heading" role="tab"> | |
88 | - <div class="row"> | |
89 | - <div class="col-xs-9 col-md-9 titleTopic"> | |
90 | - <a role="button" data-toggle="collapse" data-parent="#accordion" href=".collapseOne" aria-expanded="false" aria-controls="collapseOne" class="collapsed"> | |
91 | - <h4 style="color:white">{{course.name}}</h4> | |
92 | - </a> | |
93 | - </div> | |
94 | - {% if user|has_role:'professor' or user|has_role:'system_admin' %} | |
95 | - <div class="col-xs-4 col-md-3" id="divMoreActions"> | |
96 | - <div class="btn-group"> | |
97 | - <button class="btn btn-default btn-sm dropdown-toggle" type="button" id="moreActions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> | |
98 | - <i class="fa fa-ellipsis-v fa-2x" aria-hidden="true"></i> | |
99 | - </button> | |
100 | - <ul class="dropdown-menu" aria-labelledby="moreActions"> | |
101 | - <li><a href="javascript:void(0)" data-toggle="modal" data-target="#myModal4"><i class="fa fa-files-o fa-fw" aria-hidden="true"></i> Replicate</a></li> | |
102 | - <li><a href="javascript:void(0)" data-toggle="modal" data-target="#removeCourse"><i class="fa fa-trash fa-fw" aria-hidden="true"></i> Remove</a></li> | |
103 | - </ul> | |
104 | - </div> | |
105 | - </div> | |
106 | - {% endif %} | |
107 | - </div> | |
108 | - </div> | |
109 | - <div class="panel-collapse collapseOne collapse in" role="tabpanel" aria-labelledby="headingOne" aria-expanded="true" aria-hidden="false" tabindex="0"> | |
110 | - <div class="panel-body"> | |
111 | - <p><b>Course Name: </b>{{course.name}}</p> | |
112 | - <p><b>Duration (in semesters): </b>09</p> | |
113 | - <p><b>Coordinator: </b>{{course.professors}}</p> | |
114 | - <p> | |
115 | - <b>Description:</b> | |
116 | - <i> | |
117 | - {{course.description}} | |
118 | - </i> | |
119 | - </p> | |
120 | - <a href="{% url 'course:view' course.slug %}" class="btn btn-raised btn-default center-block">{% trans 'View Course' %}<div class="ripple-container"></div></a> | |
121 | - </div> | |
122 | - </div> | |
123 | - </div> | |
124 | - </div> | |
125 | - </div> | |
99 | + {% include "course/course_card.html" %} | |
126 | 100 | {% endif %} |
127 | 101 | {% endfor %} |
128 | 102 | {% endif %} |
129 | 103 | {% else %} |
130 | 104 | {% trans 'No courses found' %} |
131 | 105 | {% endif %} |
132 | - <div class="group"> | |
133 | - <div class="modal" id="removeCourse"> | |
134 | - <div class="modal-dialog"> | |
135 | - <div class="modal-content"> | |
136 | - <div class="modal-header"> | |
137 | - <button type="button" class="close" data-dismiss="modal" aria-hidden="true">X</button> | |
138 | - <h4 class="modal-title"></h4> | |
139 | - </div> | |
140 | - <div class="modal-body"> | |
141 | - <p>Delete your course?</p> | |
142 | - </div> | |
143 | - <div class="modal-footer"> | |
144 | - | |
145 | - <a href="http://127.0.0.1:8080/html/screens/users/profile_user.html" target="_self"><button type="button" class="btn btn-primary">Confirm</button></a> | |
146 | - | |
147 | - </div> | |
148 | - </div> | |
149 | - </div> | |
150 | - </div> | |
151 | - </div> | |
152 | 106 | </div> |
153 | 107 | <div class="col-md-12"> |
154 | 108 | <nav aria-label="Page navigation"> |
... | ... | @@ -171,4 +125,6 @@ |
171 | 125 | </ul> |
172 | 126 | </nav> |
173 | 127 | </div> |
128 | + | |
129 | + <script type="text/javascript" src="{% static 'js/course.js' %}"></script> | |
174 | 130 | {% endblock %} | ... | ... |
... | ... | @@ -0,0 +1,135 @@ |
1 | +{% extends 'course/view.html' %} | |
2 | + | |
3 | +{% load static i18n %} | |
4 | +{% load widget_tweaks %} | |
5 | + | |
6 | +{% block breadcrumbs %} | |
7 | + <ol class="breadcrumb"> | |
8 | + <li><a href="{% url 'app:index' %}">{% trans 'Home' %}</a></li> | |
9 | + <li class="active">{% trans 'Replicate Course' %}</li> | |
10 | + </ol> | |
11 | +{% endblock %} | |
12 | + | |
13 | +{% block content %} | |
14 | +<div class="card card-content"> | |
15 | + <div class="card-body"> | |
16 | + <form method="post" action="" enctype="multipart/form-data">{% csrf_token %} | |
17 | + <div class="form-group is-fileinput"> | |
18 | + <label for="id_name">Name</label> | |
19 | + | |
20 | + | |
21 | + <input class="form-control" id="id_name" maxlength="100" name="name" type="text" required="" value="{{course.name}}"> | |
22 | + | |
23 | + <span class="help-block">Course name</span> | |
24 | + | |
25 | + </div> | |
26 | + | |
27 | + <div class="form-group is-fileinput"> | |
28 | + <label for="id_objectivies">Objectives</label> | |
29 | + | |
30 | + <textarea class="form-control" cols="80" id="id_objectivies" name="objectivies" rows="5">{{course.objectivies}}</textarea> | |
31 | + | |
32 | + <span class="help-block">Course objective</span> | |
33 | + | |
34 | + </div> | |
35 | + | |
36 | + <div class="form-group is-fileinput"> | |
37 | + <label for="id_content">Content</label> | |
38 | + | |
39 | + | |
40 | + <textarea class="form-control" cols="80" id="id_content" name="content" rows="5">{{course.content}}</textarea> | |
41 | + | |
42 | + <span class="help-block">Course modules</span> | |
43 | + | |
44 | + </div> | |
45 | + | |
46 | + <div class="form-group is-fileinput"> | |
47 | + <label for="id_max_students">Number of studets maximum</label> | |
48 | + | |
49 | + | |
50 | + <input class="form-control" id="id_max_students" min="0" name="max_students" type="number" value="{{course.max_students}}"> | |
51 | + | |
52 | + <span class="help-block">Max number of students that a class can have</span> | |
53 | + | |
54 | + </div> | |
55 | + | |
56 | + <div class="form-group is-fileinput"> | |
57 | + <label for="id_init_register_date">Course registration start date</label> | |
58 | + | |
59 | + | |
60 | + <input type="date" class="form-control" name="init_register_date" value="None" min="2016-10-24"> | |
61 | + | |
62 | + <span class="help-block">Date that starts the registration period of the course (dd/mm/yyyy)</span> | |
63 | + | |
64 | + </div> | |
65 | + | |
66 | + <div class="form-group is-fileinput"> | |
67 | + <label for="id_end_register_date">Course registration end date</label> | |
68 | + | |
69 | + | |
70 | + <input type="date" class="form-control" name="end_register_date" value="None" min="2016-10-24"> | |
71 | + | |
72 | + <span class="help-block">Date that ends the registration period of the course (dd/mm/yyyy)</span> | |
73 | + | |
74 | + </div> | |
75 | + | |
76 | + <div class="form-group is-fileinput"> | |
77 | + <label for="id_init_date">Course start date</label> | |
78 | + | |
79 | + | |
80 | + <input type="date" class="form-control" name="init_date" value="None" min="2016-10-24"> | |
81 | + | |
82 | + <span class="help-block">Date that the course starts (dd/mm/yyyy)</span> | |
83 | + | |
84 | + </div> | |
85 | + | |
86 | + <div class="form-group is-fileinput"> | |
87 | + <label for="id_end_date">Course end date</label> | |
88 | + | |
89 | + | |
90 | + <input type="date" class="form-control" name="end_date" value="None" min="2016-10-24"> | |
91 | + | |
92 | + <span class="help-block">Date that the course ends (dd/mm/yyyy)</span> | |
93 | + | |
94 | + </div> | |
95 | + | |
96 | + <div class="form-group is-fileinput"> | |
97 | + <label for="id_image">Imagem</label> | |
98 | + | |
99 | + | |
100 | + <input class="form-control" id="id_image" name="image" type="file"> | |
101 | + <div class="input-group"> | |
102 | + <input type="text" readonly="" class="form-control" placeholder="Choose your photo..."> | |
103 | + <span class="input-group-btn input-group-sm"> | |
104 | + <button type="button" class="btn btn-fab btn-fab-mini"> | |
105 | + <i class="material-icons">attach_file</i> | |
106 | + </button> | |
107 | + </span> | |
108 | + </div> | |
109 | + | |
110 | + <span class="help-block">Representative image of the course</span> | |
111 | + | |
112 | + </div> | |
113 | + | |
114 | + <div class="form-group is-fileinput"> | |
115 | + <label for="id_category">CourseCategory</label> | |
116 | + | |
117 | + | |
118 | + <select class="form-control" id="id_category" name="category" required=""> | |
119 | + {% for category in categorys_courses %} | |
120 | + <option value="{{category.id}}">{{category}}</option> | |
121 | + {% endfor %} | |
122 | + </select> | |
123 | + | |
124 | + <span class="help-block">CourseCategory which the course belongs</span> | |
125 | + | |
126 | + </div> | |
127 | + | |
128 | + <div class="row text-center"> | |
129 | + <input type="submit" value="Create" class="btn btn-primary"> | |
130 | + </div> | |
131 | + </form> | |
132 | + </div> | |
133 | +</div> | |
134 | +</br> | |
135 | +{% endblock %} | |
0 | 136 | \ No newline at end of file | ... | ... |
courses/templates/course/view.html
courses/urls.py
... | ... | @@ -4,6 +4,7 @@ from . import views |
4 | 4 | urlpatterns = [ |
5 | 5 | url(r'^$', views.IndexView.as_view(), name='manage'), |
6 | 6 | url(r'^create/$', views.CreateCourseView.as_view(), name='create'), |
7 | + url(r'^replicate_course/(?P<slug>[\w_-]+)/$', views.ReplicateCourseView.as_view(), name='replicate_course'), | |
7 | 8 | url(r'^edit/(?P<slug>[\w_-]+)/$', views.UpdateCourseView.as_view(), name='update'), |
8 | 9 | url(r'^(?P<slug>[\w_-]+)/$', views.CourseView.as_view(), name='view'), |
9 | 10 | url(r'^delete/(?P<slug>[\w_-]+)/$', views.DeleteCourseView.as_view(), name='delete'), |
... | ... | @@ -12,7 +13,6 @@ urlpatterns = [ |
12 | 13 | url(r'^categories/view/$', views.IndexCatView.as_view(), name='manage_cat'), |
13 | 14 | url(r'^categories/create/$', views.CreateCatView.as_view(), name="create_cat"), |
14 | 15 | url(r'^categories/edit/(?P<slug>[\w_-]+)/$', views.UpdateCatView.as_view(), name='update_cat'), |
15 | - url(r'^categories/(?P<slug>[\w_-]+)/$', views.ViewCat.as_view(), name='view_cat'), | |
16 | 16 | url(r'^categories/delete/(?P<slug>[\w_-]+)/$', views.DeleteCatView.as_view(), name='delete_cat'), |
17 | 17 | url(r'^subjects/(?P<slug>[\w_-]+)/$', views.SubjectsView.as_view(), name='view_subject'), |
18 | 18 | url(r'^subjects/create/(?P<slug>[\w_-]+)/$', views.CreateSubjectView.as_view(), name='create_subject'), | ... | ... |
courses/views.py
... | ... | @@ -36,9 +36,12 @@ class IndexView(LoginRequiredMixin, NotificationMixin, generic.ListView): |
36 | 36 | context = super(IndexView, self).get_context_data(**kwargs) |
37 | 37 | list_courses = None |
38 | 38 | categorys_courses = None |
39 | - if has_role(self.request.user,'professor') or has_role(self.request.user,'system_admin'): | |
39 | + if has_role(self.request.user,'professor'): | |
40 | 40 | list_courses = Course.objects.filter(Q(professors = True)|Q(professors__name = self.request.user.name)).order_by('name') |
41 | 41 | categorys_courses = CourseCategory.objects.filter(course_category__professors__name = self.request.user.name).distinct() |
42 | + elif has_role(self.request.user,'system_admin'): | |
43 | + list_courses = queryset.order_by('name') | |
44 | + categorys_courses = CourseCategory.objects.all() | |
42 | 45 | else: |
43 | 46 | list_courses = Course.objects.filter(Q(students = True)|Q(students__name = self.request.user.name)).order_by('name') |
44 | 47 | categorys_courses = CourseCategory.objects.filter(course_category__students__name = self.request.user.name).distinct() |
... | ... | @@ -102,6 +105,38 @@ class CreateCourseView(LoginRequiredMixin, HasRoleMixin, NotificationMixin,gener |
102 | 105 | context['now'] = date.today() |
103 | 106 | return context |
104 | 107 | |
108 | +class ReplicateCourseView(LoginRequiredMixin, HasRoleMixin, NotificationMixin,generic.edit.CreateView): | |
109 | + | |
110 | + allowed_roles = ['professor', 'system_admin'] | |
111 | + login_url = reverse_lazy("core:home") | |
112 | + redirect_field_name = 'next' | |
113 | + template_name = 'course/replicate.html' | |
114 | + form_class = CourseForm | |
115 | + success_url = reverse_lazy('course:manage') | |
116 | + | |
117 | + def form_valid(self, form): | |
118 | + self.object = form.save() | |
119 | + self.object.professors.add(self.request.user) | |
120 | + return super(ReplicateCourseView, self).form_valid(form) | |
121 | + | |
122 | + def get_context_data(self, **kwargs): | |
123 | + context = super(ReplicateCourseView, self).get_context_data(**kwargs) | |
124 | + course = get_object_or_404(Course, slug = self.kwargs.get('slug')) | |
125 | + if has_role(self.request.user,'system_admin'): | |
126 | + courses = Course.objects.all() | |
127 | + elif has_role(self.request.user,'professor'): | |
128 | + courses = self.request.user.courses.all() | |
129 | + categorys_courses = CourseCategory.objects.all() | |
130 | + context['courses'] = courses | |
131 | + context['course'] = course | |
132 | + context['categorys_courses'] = categorys_courses | |
133 | + context['title'] = _("Replicate Course") | |
134 | + context['now'] = date.today() | |
135 | + return context | |
136 | + | |
137 | + def get_success_url(self): | |
138 | + return reverse_lazy('course:view', kwargs={'slug' : self.object.slug}) | |
139 | + | |
105 | 140 | class UpdateCourseView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView): |
106 | 141 | |
107 | 142 | allowed_roles = ['professor', 'system_admin'] |
... | ... | @@ -133,8 +168,6 @@ class UpdateCourseView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView): |
133 | 168 | def get_success_url(self): |
134 | 169 | return reverse_lazy('course:view', kwargs={'slug' : self.object.slug}) |
135 | 170 | |
136 | - | |
137 | - | |
138 | 171 | class DeleteCourseView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView): |
139 | 172 | |
140 | 173 | allowed_roles = ['professor', 'system_admin'] |
... | ... | @@ -297,13 +330,6 @@ class UpdateCatView(LoginRequiredMixin, HasRoleMixin, generic.UpdateView): |
297 | 330 | messages.success(self.request, _('Category updated successfully!')) |
298 | 331 | return reverse_lazy('course:update_cat', kwargs={'slug' : self.object.slug}) |
299 | 332 | |
300 | -class ViewCat(LoginRequiredMixin, generic.DetailView): | |
301 | - login_url = reverse_lazy("core:home") | |
302 | - redirect_field_name = 'next' | |
303 | - model = CourseCategory | |
304 | - template_name = 'category/view.html' | |
305 | - context_object_name = 'category' | |
306 | - | |
307 | 333 | class DeleteCatView(LoginRequiredMixin, HasRoleMixin, generic.DeleteView): |
308 | 334 | |
309 | 335 | allowed_roles = ['professor', 'system_admin'] | ... | ... |