diff options
author | adityacp | 2021-02-10 19:02:29 +0530 |
---|---|---|
committer | adityacp | 2021-02-10 19:02:29 +0530 |
commit | 8c1c1f6c8b1de16fba5f93e58a0cd3cb751e02d7 (patch) | |
tree | f55b9b990e1b4881d91770d6304cc9059ffaf1f3 /yaksh | |
parent | c179633d31dbdd1bb4cc9a6e157664bc5712756c (diff) | |
download | online_test-8c1c1f6c8b1de16fba5f93e58a0cd3cb751e02d7.tar.gz online_test-8c1c1f6c8b1de16fba5f93e58a0cd3cb751e02d7.tar.bz2 online_test-8c1c1f6c8b1de16fba5f93e58a0cd3cb751e02d7.zip |
Change in templates, views
- Revamp UI in course page
- Fix a bug where a trial module is created without setting is_trial in
models
- Fix a bug in question statistics where only completed answerpaper data
is needed
Diffstat (limited to 'yaksh')
-rw-r--r-- | yaksh/models.py | 2 | ||||
-rw-r--r-- | yaksh/static/yaksh/css/custom.css | 2 | ||||
-rw-r--r-- | yaksh/templates/yaksh/courses.html | 227 | ||||
-rw-r--r-- | yaksh/templates/yaksh/micromonitor.html | 6 | ||||
-rw-r--r-- | yaksh/templates/yaksh/monitor.html | 333 | ||||
-rw-r--r-- | yaksh/views.py | 12 |
6 files changed, 284 insertions, 298 deletions
diff --git a/yaksh/models.py b/yaksh/models.py index b4d0f76..5934ae2 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -2027,7 +2027,7 @@ class AnswerPaperManager(models.Manager): que_ids = [que.id for que in all_questions] papers = self.filter( question_paper_id=questionpaper_id, course_id=course_id, - attempt_number=attempt_number + attempt_number=attempt_number, status=status ).values_list("id", flat=True) answers = Answer.objects.filter( answerpaper__id__in=papers, question_id__in=que_ids diff --git a/yaksh/static/yaksh/css/custom.css b/yaksh/static/yaksh/css/custom.css index 78eaba4..c722197 100644 --- a/yaksh/static/yaksh/css/custom.css +++ b/yaksh/static/yaksh/css/custom.css @@ -211,3 +211,5 @@ iframe { width: 100%; text-align: center; } + +.dropdown:hover .dropdown-menu {display: block;}
\ No newline at end of file diff --git a/yaksh/templates/yaksh/courses.html b/yaksh/templates/yaksh/courses.html index 02cbad9..b9e48d6 100644 --- a/yaksh/templates/yaksh/courses.html +++ b/yaksh/templates/yaksh/courses.html @@ -101,9 +101,14 @@ <br> {% for course in courses %} <div class="col-md-6"> - <div class="card border-primary"> + <div class="card"> <div class="card-header" style="height: 150px"> - {{course.name}} + <strong> + <a href="{% url 'yaksh:edit_course' course.id %}"> + <i class="fa fa-edit"></i> + {{course.name}} + </a> + </strong> <div> {% if user.id != course.creator.id %} <span class="badge badge-pill badge-warning"> @@ -115,86 +120,70 @@ </span> {% endif %} </div> - </div> - <div class="card-body"> - <div class="row"> - <div class="col"> - <strong>Starts On:</strong> - {{course.start_enroll_time}} - <br> - <strong>Ends On:</strong> - {{course.end_enroll_time}} - </div> - </div> - <hr> - <div class="row"> - <div class="col-md-3"> - {% if course.active %} - <span class="badge badge-pill badge-success"> - Active - </span> - {% else %} - <span class="badge badge-pill badge-danger"> - Inactive - </span> - {% endif %} - </div> - <div class="col-md-4"> - <a href="{% url 'yaksh:toggle_course_status' course.id %}"> + <div> + <div class="nav-item dropdown"> + <a class="dropdown-toggle nav-link" data-toggle="dropdown" href="#" style="color: blue;">More + </a> + <div class="dropdown-menu dropdown-menu-right"> + <a class="dropdown-item" href="{% url 'yaksh:toggle_course_status' course.id %}"> {% if course.active %} <i class="fa fa-toggle-on fa-2x"></i> + Deactivate Course {% else %} <i class="fa fa-toggle-off fa-2x"></i> + Activate Course {% endif %} </a> - </div> - </div> - <hr> - <div class="row"> - <div class="col-md-5"> - <a href="{% url 'yaksh:edit_course' course.id %}" class="btn btn-info"> - <i class="fa fa-edit"></i> - Edit - </a> - </div> - <div class="col-md-5"> - <a href="{% url 'yaksh:course_detail' course.id %}" class="btn btn-primary"> + <div class="dropdown-divider"></div> + <a class="dropdown-item" href="{% url 'yaksh:course_detail' course.id %}"> <i class="fa fa-tasks"></i> - Manage + Manage Course </a> - </div> - </div> - <br> - <div class="row"> - <div class="col-md-5"> - <a href="{% url 'yaksh:duplicate_course' course.id %}" class="btn btn-secondary"> + <div class="dropdown-divider"></div> + <a class="dropdown-item" href="{% url 'yaksh:duplicate_course' course.id %}"> <i class="fa fa-clone"></i> - Clone + Clone Course </a> - </div> - <div class="col-md-5"> - <div class="btn-group" role="group" aria-label="Button group with nested dropdown"> - <button type="button" class="btn btn-secondary"> - <i class="fa fa-download"></i> - Download - </button> - <div class="btn-group" role="group"> - <button id="btnGroupDrop1" type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></button> - <div class="dropdown-menu" aria-labelledby="btnGroupDrop1" style=""> + <div class="dropdown-divider"></div> <a class="dropdown-item" href="{% url 'yaksh:download_course_csv' course.id %}"> - CSV + <i class="fa fa-download"></i> + Download CSV </a> + <div class="dropdown-divider"></div> <a class="dropdown-item" href="{% url 'yaksh:download_course' course.id %}"> - Course + <i class="fa fa-download"></i> + Download Course </a> </div> - </div> - </div> + </div> + </div> + </div> + <div class="card-body"> + <div class="row"> + <div class="col-md-8"> + <strong>Status:</strong> + {% if course.active %} + <span class="badge badge-pill badge-success"> + Active + </span> + {% else %} + <span class="badge badge-pill badge-danger"> + Inactive + </span> + {% endif %} + <br> + <strong>Creator:</strong> + {{course.creator.get_full_name}} + <br> + <strong>Starts On:</strong> + {{course.start_enroll_time}} + <br> + <strong>Ends On:</strong> + {{course.end_enroll_time}} </div> </div> </div> </div> - <br> </div> {% endfor %} <br> @@ -207,8 +196,13 @@ <div class="card"> <div class="card-header bg-secondary"> <div class="row"> - <div class="col-md-5"> - {{course.name}} + <div class="col-md-7"> + <strong> + <a href="{% url 'yaksh:edit_course' course.id %}"> + <i class="fa fa-edit"></i> + {{course.name}} + </a> + </strong> </div> <div class="col-md-3"> {% if user.id != course.creator.id %} @@ -221,7 +215,49 @@ </span> {% endif %} </div> - <div class="col-md-2"> + <div class="col"> + <li class="nav-item dropdown"> + <a class="dropdown-toggle nav-link" id="user_dropdown" data-toggle="dropdown" href="#" style="color: blue;">More + </a> + <div class="dropdown-menu dropdown-menu-right"> + <a class="dropdown-item" href="{% url 'yaksh:toggle_course_status' course.id %}"> + {% if course.active %} + <i class="fa fa-toggle-on fa-2x"></i> + Deactivate Course + {% else %} + <i class="fa fa-toggle-off fa-2x"></i> + Activate Course + {% endif %} + </a> + <div class="dropdown-divider"></div> + <a class="dropdown-item" href="{% url 'yaksh:course_detail' course.id %}"> + <i class="fa fa-tasks"></i> + Manage Course + </a> + <div class="dropdown-divider"></div> + <a class="dropdown-item" href="{% url 'yaksh:duplicate_course' course.id %}"> + <i class="fa fa-clone"></i> + Clone Course + </a> + <div class="dropdown-divider"></div> + <a class="dropdown-item" href="{% url 'yaksh:download_course_csv' course.id %}"> + <i class="fa fa-download"></i> + Download CSV + </a> + <div class="dropdown-divider"></div> + <a class="dropdown-item" href="{% url 'yaksh:download_course' course.id %}"> + <i class="fa fa-download"></i> + Download Course + </a> + </div> + </li> + </div> + </div> + </div> + <div class="card-body"> + <div class="row"> + <div class="col"> + <strong>Status:</strong> {% if course.active %} <span class="badge badge-pill badge-success"> Active @@ -231,21 +267,10 @@ Inactive </span> {% endif %} - </div> - <div class="col-md-2"> - <a href="{% url 'yaksh:toggle_course_status' course.id %}"> - {% if course.active %} - <i class="fa fa-toggle-on fa-2x"></i> - {% else %} - <i class="fa fa-toggle-off fa-2x"></i> - {% endif %} - </a> - </div> - </div> - </div> - <div class="card-body"> - <div class="row"> - <div class="col"> + <br> + <strong>Creator:</strong> + {{course.creator.get_full_name}} + <br> <strong>Starts On:</strong> {{course.start_enroll_time}} <br> @@ -253,46 +278,6 @@ {{course.end_enroll_time}} </div> </div> - <hr> - <div class="row"> - <div class="col-md-3"> - <a href="{% url 'yaksh:edit_course' course.id %}" class="btn btn-info"> - <i class="fa fa-edit"></i> - Edit - </a> - </div> - <div class="col-md-3"> - <a href="{% url 'yaksh:course_detail' course.id %}" class="btn btn-primary"> - <i class="fa fa-tasks"></i> - Manage - </a> - </div> - <div class="col-md-3"> - <a href="{% url 'yaksh:duplicate_course' course.id %}" class="btn btn-secondary"> - <i class="fa fa-clone"></i> - Clone - </a> - </div> - <div class="col-md-3"> - <div class="btn-group" role="group" aria-label="Button group with nested dropdown"> - <button type="button" class="btn btn-secondary"> - <i class="fa fa-download"></i> - Download - </button> - <div class="btn-group" role="group"> - <button id="btnGroupDrop1" type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></button> - <div class="dropdown-menu" aria-labelledby="btnGroupDrop1" style=""> - <a class="dropdown-item" href="{% url 'yaksh:download_course_csv' course.id %}"> - CSV - </a> - <a class="dropdown-item" href="{% url 'yaksh:download_course' course.id %}"> - Course - </a> - </div> - </div> - </div> - </div> - </div> </div> </div> <br> diff --git a/yaksh/templates/yaksh/micromonitor.html b/yaksh/templates/yaksh/micromonitor.html index cc059aa..bc64469 100644 --- a/yaksh/templates/yaksh/micromonitor.html +++ b/yaksh/templates/yaksh/micromonitor.html @@ -1,9 +1,9 @@ {% if micromanager %} {% if micromanager.can_student_attempt %} - <a class="btn btn-danger" href="{% url 'yaksh:revoke_special_attempt' micromanager.id %}">Revoke</a> + <a class="btn btn-danger btn-sm" href="{% url 'yaksh:revoke_special_attempt' micromanager.id %}">Revoke</a> {% else %} - <a class="btn btn-success" href="{% url 'yaksh:allow_special_attempt' user_id course_id quiz_id %}">Allow </a> + <a class="btn btn-success btn-sm" href="{% url 'yaksh:allow_special_attempt' user_id course_id quiz_id %}">Allow </a> {% endif %} {% else %} - <a class="btn btn-success" href="{% url 'yaksh:allow_special_attempt' user_id course_id quiz_id %}">Allow </a> + <a class="btn btn-success btn-sm" href="{% url 'yaksh:allow_special_attempt' user_id course_id quiz_id %}">Allow </a> {% endif %} diff --git a/yaksh/templates/yaksh/monitor.html b/yaksh/templates/yaksh/monitor.html index ca5a7fc..9b10b58 100644 --- a/yaksh/templates/yaksh/monitor.html +++ b/yaksh/templates/yaksh/monitor.html @@ -52,8 +52,9 @@ $(document).ready(function() {% if quiz %} {% if papers %} <div class="row"> - <div class="card col"> - <div class="table-responsive"> + <div class="card col-md-3"> + <div class="card-body"> + <div class="table-responsive"> <table id="course-detail" class="table"> <tr> <td><b>Course Name: </b></td> @@ -63,186 +64,180 @@ $(document).ready(function() <td><b>Quiz Name: </b></td> <td>{{quiz.description}}</td> </tr> - </table> - </div> - </div> - <div class="card col"> - <div class="table-responsive"> - <table id="course-detail" class="table"> - <tr> + <tr> <td><b>Number of papers:  </b></td> <td>{{total_papers}}</td> - </tr> - <tr> - <td><b>Papers Completed:  </b></td> - <td> - <b>{{completed_papers}}</b> - </td> - </tr> - <tr> - <td><b>Papers in progress:  </b></td> - <td> - <b>{{ inprogress_papers }}</b> - </td> - </tr> - </table> + </tr> + <tr> + <td><b>Papers Completed:  </b></td> + <td> + <b>{{completed_papers}}</b> + </td> + </tr> + <tr> + <td><b>Papers in progress:  </b></td> + <td> + <b>{{ inprogress_papers }}</b> + </td> + </tr> + </table> + </div> </div> </div> - </div> - <div class="row"> - <div class="col-md-4"> - <button type="button" class="btn btn-info" data-toggle="modal" data-target="#csvModal"> - <i class="fa fa-download"></i> Download CSV - </button> - </div> - <div class="col-md-4"> - <a href="{% url 'yaksh:show_statistics' papers.0.question_paper.id course.id %}" class="btn btn-primary"> - <i class="fa fa-line-chart"></i> Question Statistics - </a> + <div class="col-md-9"> + <div class="row"> + <div class="col-md-4"> + <button type="button" class="btn btn-info" data-toggle="modal" data-target="#csvModal"> + <i class="fa fa-download"></i> Download CSV + </button> + </div> + <div class="col-md-4"> + <a href="{% url 'yaksh:show_statistics' papers.0.question_paper.id course.id %}" class="btn btn-primary"> + <i class="fa fa-line-chart"></i> Question Statistics + </a> + </div> + <div class="col-md-4"> + <div class="badge badge-info"> + Auto-Refreshes every 5 minutes + </div> + </div> </div> - <div class="col-md-4"> - <div class="badge badge-info"> - Auto-Refreshes every 5 minutes + <hr> + <div class="row"> + <div class="col-md-4"> + <p> + <b> + - Download the CSV file from the button above<br /> + - Edit and upload the same <br /> + </b> + </p> + </div> + <div class="col-md-6"> + <form id="upload_users" action="{% url 'yaksh:upload_marks' course.id papers.0.question_paper.id %}" method="POST" enctype="multipart/form-data"> + {% csrf_token %} + <input type="file" class="custom-file-input" name="csv_file" id="upload"/> + <button class="btn btn-outline-primary" type="submit"> + <i class="fa fa-upload"></i> + Upload + </button> + </form> </div> </div> - </div> - <hr> - <div class="row"> - <div class="col-md-4"> - <p> - <b> - - Download the CSV file from the button above<br /> - - Edit and upload the same <br /> - </b> - </p> + <br> + <div class="card"> + {% if total_papers > 10 %} + <div class="table-responsive" style="height: 800px"> + {% else %} + <div class="table-responsive"> + {% endif %} + <table id="result-table" class="table table-dark table-responsive-sm"> + <thead class="thead-dark"> + <tr> + <th> Sr No. </th> + <th> Name <i class="fa fa-sort"></i> </th> + <th> Roll No <i class="fa fa-sort"></i> </th> + <th> Marks <i class="fa fa-sort"></i> </th> + <th> Questions Attempted <i class="fa fa-sort"></i> </th> + <th> Time Left <i class="fa fa-sort"></i> </th> + <th> Status <i class="fa fa-sort"></i> </th> + <th> Time Extension <i class="fa fa-sort"></i> </th> + <th> Special Attempt <i class="fa fa-sort"></i> </th> + </tr> + </thead> + <tbody class="list"> + {% for paper in papers %} + <tr> + <td>{{forloop.counter}}</td> + {% with paper.user as student %} + <td> + <i class="fa fa-edit"></i> + <a href="{% url 'yaksh:user_data' paper.user_id paper.question_paper_id course.id %}" class="text-white"> + {{ student.get_full_name.title }} + </a> + </td> + <td> {{ student.profile.roll_number }} </td> + {% endwith %} + <td> {{ paper.marks_obtained }} </td> + <td> + {% get_dict_value questions_attempted paper.id as que_attempt %} + {{que_attempt}} out of {{questions_count}} + </td> + <td id="time_left{{forloop.counter0}}"> {{ paper.time_left }} </td> + <td> {% if paper.is_attempt_inprogress %} + <span class="badge badge-warning"> Inprogress </span> + {% else %} + <span class="badge badge-success"> Completed </span> + {% endif %} + </td> + <td> + <form method="post" action="{% url 'yaksh:extend_time' paper.id %}"> + {% csrf_token %} + <div class="input-group"> + <input type="number" step="any" class="form-control form-control-sm" id="extra_time" name="extra_time" required> + <div class="input-group-append"> + <button class="btn btn-outline-success btn-sm" type="submit"> + <i class="fa fa-plus"></i> + </button> + </div> + </div> + </form> + </td> + <td>{% specail_attempt_monitor paper.user.id course.id quiz.id %}</td> + </tr> + {% endfor %} + </tbody> + </table> + </div> </div> - <div class="col-md-6"> - <form id="upload_users" action="{% url 'yaksh:upload_marks' course.id papers.0.question_paper.id %}" method="POST" enctype="multipart/form-data"> + <!-- CSV Modal --> + <div class="modal fade" id="csvModal" role="dialog"> + <div class="modal-dialog"> + <!-- Modal content--> + <div class="modal-content"> + <div class="modal-header"> + <h3 class="modal-title">Download CSV for {{quiz.description}} </h3> + <button type="button" class="close" data-dismiss="modal"> + <i class="fa fa-close"></i> + </button> + </div> + <form action="{% url 'yaksh:download_quiz_csv' course.id quiz.id %}" method="post"> {% csrf_token %} - <div class="input-group"> - <div class="custom-file"> - <input type="file" class="custom-file-input" name="csv_file" id="upload"/> - <label class="custom-file-label" for="upload">Select</label> + <div class="modal-body"> + <b>Select Attempt Number: Default latest attempt</b> + <select class="form-control" name = "attempt_number"> + {% for attempt_number in attempt_numbers %} + {% if forloop.last %} + <option value="{{ attempt_number }}" selected>{{ attempt_number }} (Latest)</option> + {% else %} + <option value = "{{ attempt_number }}"> {{ attempt_number }}</option> + {% endif %} + {% endfor %} + </select> </div> - <div class="input-group-append"> - <button class="btn btn-outline-primary" type="submit"> - <i class="fa fa-upload"></i> - Upload - </button> + <div class="modal-footer"> + <button type="submit" class="btn btn-success"> + <span class="fa fa-save"></span> Download + </button> + <button type="button" class="btn btn-secondary" data-dismiss="modal"> + Close + </button> + </div> + </form> </div> </div> - </form> - </div> - </div> - <br> - <div class="card"> - {% if total_papers > 10 %} - <div class="table-responsive" style="height: 800px"> - {% else %} - <div class="table-responsive"> - {% endif %} - <table id="result-table" class="table table-dark table-responsive-sm"> - <thead class="thead-dark"> - <tr> - <th> Sr No. </th> - <th> Name <i class="fa fa-sort"></i> </th> - <th> Roll No <i class="fa fa-sort"></i> </th> - <th> Marks <i class="fa fa-sort"></i> </th> - <th> Questions Attempted <i class="fa fa-sort"></i> </th> - <th> Time Left <i class="fa fa-sort"></i> </th> - <th> Status <i class="fa fa-sort"></i> </th> - <th> Extend time <i class="fa fa-sort"></i> </th> - <th> Special Attempt <i class="fa fa-sort"></i> </th> - </tr> - </thead> - <tbody class="list"> - {% for paper in papers %} - <tr> - <td>{{forloop.counter}}</td> - {% with paper.user as student %} - <td> <a href="{% url 'yaksh:user_data' paper.user_id paper.question_paper_id course.id %}"> - {{ student.get_full_name.title }}</a> </td> - <td> {{ student.profile.roll_number }} </td> - {% endwith %} - <td> {{ paper.marks_obtained }} </td> - <td> - {% get_dict_value questions_attempted paper.id as que_attempt %} - {{que_attempt}} out of {{questions_count}} - </td> - <td id="time_left{{forloop.counter0}}"> {{ paper.time_left }} </td> - <td> {% if paper.is_attempt_inprogress %} - <span class="badge badge-warning"> Inprogress </span> - {% else %} - <span class="badge badge-success"> Completed </span> - {% endif %} - </td> - <td width="15%"> - <form method="post" action="{% url 'yaksh:extend_time' paper.id %}"> - {% csrf_token %} - <div class="input-group mb-3"> - <input type="number" step="any" class="form-control" id="extra_time" name="extra_time" required> - <div class="input-group-append"> - <button class="btn btn-outline-secondary" type="submit" width="10"> - <i class="fa fa-plus"></i> - </button> - </div> - </div> - </form> - </td> - <td>{% specail_attempt_monitor paper.user.id course.id quiz.id %}</td> - </tr> - {% endfor %} - </tbody> - </table> </div> - </div> - <!-- CSV Modal --> - <div class="modal fade" id="csvModal" role="dialog"> - <div class="modal-dialog"> - <!-- Modal content--> - <div class="modal-content"> - <div class="modal-header"> - <h3 class="modal-title">Download CSV for {{quiz.description}} </h3> - <button type="button" class="close" data-dismiss="modal"> - <i class="fa fa-close"></i> - </button> - </div> - <form action="{% url 'yaksh:download_quiz_csv' course.id quiz.id %}" method="post"> - {% csrf_token %} - <div class="modal-body"> - <b>Select Attempt Number: Default latest attempt</b> - <select class="form-control" name = "attempt_number"> - {% for attempt_number in attempt_numbers %} - {% if forloop.last %} - <option value="{{ attempt_number }}" selected>{{ attempt_number }} (Latest)</option> - {% else %} - <option value = "{{ attempt_number }}"> {{ attempt_number }}</option> - {% endif %} - {% endfor %} - </select> + {% else %} + <div class="col-md-12"> + <div class="alert alert-warning"> + <center> + <p>No Users Found for {{ quiz.description }}</p> + </center> </div> - <div class="modal-footer"> - <button type="submit" class="btn btn-success"> - <span class="fa fa-save"></span> Download - </button> - <button type="button" class="btn btn-secondary" data-dismiss="modal"> - Close - </button> - </div> - </form> - </div> - </div> - </div> - {% else %} - <div class="col-md-12"> - <div class="alert alert-warning"> - <center> - <p>No Users Found for {{ quiz.description }}</p> - </center> </div> - </div> - {% endif %} {# if papers #} - {% else %} - <h4>No Quiz Found</h4> - {% endif %} + {% endif %} {# if papers #} + {% else %} + <h4>No Quiz Found</h4> + {% endif %} + </div> +</div> {% endblock %} diff --git a/yaksh/views.py b/yaksh/views.py index 83b6766..1225b0e 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -2137,7 +2137,7 @@ def test_mode(user, godmode=False, questions_list=None, quiz_id=None, order=1, type="quiz", quiz=trial_quiz, check_prerequisite=False) module, created = LearningModule.objects.get_or_create( - order=1, creator=user, check_prerequisite=False, + order=1, creator=user, check_prerequisite=False, is_trial=True, name="Trial for {0}".format(trial_course.name)) module.learning_unit.add(trial_unit) trial_course.learning_module.add(module.id) @@ -2164,12 +2164,16 @@ def test_quiz(request, mode, quiz_id, course_id=None): request, "{0} is either expired or inactive".format(quiz.description) ) - return my_redirect('/exam/manage') + return my_redirect(reverse("yaksh:index")) trial_questionpaper, trial_course, trial_module = test_mode( current_user, godmode, None, quiz_id, course_id) - return my_redirect("/exam/start/{0}/{1}/{2}".format( - trial_questionpaper.id, trial_module.id, trial_course.id)) + return my_redirect( + reverse( + "yaksh:start_quiz", + args=[trial_questionpaper.id, trial_module.id, trial_course.id] + ) + ) @login_required |