Skip to content

Commit

Permalink
Quiz : améliorer le tableau des questions (#1991)
Browse files Browse the repository at this point in the history
* QuizQuestion: replace HTML table with tables2

* Use verbose_name instead of gettext_lazy
  • Loading branch information
raphodn committed Nov 12, 2023
1 parent debad6e commit 1b6ad7a
Show file tree
Hide file tree
Showing 11 changed files with 87 additions and 55 deletions.
2 changes: 1 addition & 1 deletion app/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@

SHELL_PLUS = "ipython"
SHELL_PLUS_IMPORTS = [
"import csv, json, yaml",
"import csv, json, yaml, time",
"from datetime import datetime, date, timedelta",
"from core import constants",
"from core.utils import utilities, notion, github, sendinblue, s3",
Expand Down
4 changes: 2 additions & 2 deletions categories/tables.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import django_tables2 as tables
from django.db.models import Count
from django.utils.translation import gettext_lazy as _

from categories.models import Category
from core.tables import DEFAULT_ATTRS, DEFAULT_TEMPLATE, RichTextColumn
from questions.models import Question


CATEGORY_FIELD_SEQUENCE = [field.name for field in Category._meta.fields]
Expand All @@ -13,7 +13,7 @@
class CategoryTable(tables.Table):
id = tables.Column(linkify=lambda record: record.get_absolute_url())
description = RichTextColumn(attrs={"td": {"title": lambda record: record.description}})
question_count = tables.Column(verbose_name=_("Questions"))
question_count = tables.Column(verbose_name=Question._meta.verbose_name_plural)

class Meta:
model = Category
Expand Down
8 changes: 5 additions & 3 deletions contributions/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@
class CommentTable(tables.Table):
text = RichTextLongerEllipsisColumn(attrs={"td": {"title": lambda record: record.text}})
question = tables.Column(
verbose_name=_("Question"),
verbose_name=Comment._meta.get_field("question").verbose_name,
accessor="question.id",
linkify=lambda record: record.question.get_absolute_url(),
attrs={"td": {"title": lambda record: record.question}},
)
quiz = tables.Column(
verbose_name=_("Quiz"),
verbose_name=Comment._meta.get_field("quiz").verbose_name,
accessor="quiz.id",
linkify=lambda record: record.quiz.get_absolute_url(),
attrs={"td": {"title": lambda record: record.quiz}},
Expand All @@ -37,7 +37,9 @@ class CommentTable(tables.Table):
accessor="has_replies_reply_icon",
orderable=False,
)
status = tables.Column(verbose_name=_("Status"), order_by=("status_order",), accessor="status")
status = tables.Column(
verbose_name=Comment._meta.get_field("status").verbose_name, order_by=("status_order",), accessor="status"
)
processed = tables.Column(
verbose_name=_("Processed"),
accessor="processed_icon",
Expand Down
7 changes: 4 additions & 3 deletions core/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from core import constants
from core.utils.utilities import get_choice_key, remove_html_tags, truncate_with_ellipsis
from questions.models import Question
from quizs.models import QuizQuestion
from users import constants as user_constants
from users.models import User

Expand All @@ -16,9 +17,9 @@
class ChoiceColumn(tables.Column):
def render(self, value, record, bound_column):
value_title = value
if type(record) is Question:
# Question.type : display choice key
if bound_column.name == "type":
if type(record) in [Question, QuizQuestion]:
# Question.type : display choice key instead of value
if bound_column.name in ["type", "question_type"]:
value_title = value
value = get_choice_key(constants.QUESTION_TYPE_CHOICES, value)
# Question.category : add link
Expand Down
42 changes: 41 additions & 1 deletion quizs/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
from django.utils.html import format_html

from core.tables import DEFAULT_ATTRS, DEFAULT_TEMPLATE, ChoiceColumn, ImageColumn, RichTextEllipsisColumn
from quizs.models import Quiz
from questions.models import Question
from quizs.models import Quiz, QuizQuestion


QUIZ_FIELD_SEQUENCE = [
Expand Down Expand Up @@ -53,3 +54,42 @@ def __init__(self, *args, **kwargs):
for field_name in Quiz.QUIZ_TIMESTAMP_FIELDS:
self.base_columns[field_name] = tables.DateTimeColumn(format="d F Y")
super().__init__(*args, **kwargs)


QUIZ_QUESTION_FIELD_SEQUENCE = [
"question_id",
"question_text",
"question_type",
"question_author",
"question_validation_status",
"question_visibility",
"order",
]


class QuizQuestionTable(tables.Table):
question_id = tables.Column(
verbose_name=Question._meta.verbose_name,
accessor="question.id",
linkify=lambda record: record.question.get_absolute_url(),
)
question_text = RichTextEllipsisColumn(
accessor="question.text", attrs={"td": {"title": lambda record: record.question.text}}
)
question_type = ChoiceColumn(verbose_name=Question._meta.get_field("type").verbose_name, accessor="question.type")
question_author = ChoiceColumn(
verbose_name=Question._meta.get_field("author").verbose_name, accessor="question.author"
)
question_validation_status = ChoiceColumn(
verbose_name=Question._meta.get_field("validation_status").verbose_name, accessor="question.validation_status"
)
question_visibility = ChoiceColumn(
verbose_name=Question._meta.get_field("visibility").verbose_name, accessor="question.visibility"
)

class Meta:
model = QuizQuestion
fields = QUIZ_QUESTION_FIELD_SEQUENCE
sequence = QUIZ_QUESTION_FIELD_SEQUENCE
template_name = DEFAULT_TEMPLATE
attrs = DEFAULT_ATTRS
1 change: 0 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ combine_as_imports = true
ensure_newline_before_comments = true
force_grid_wrap = 0
include_trailing_comma = true
known_first_party = "lemarche"
lines_after_imports = 2
line_length = 119
multi_line_output = 3
Expand Down
8 changes: 4 additions & 4 deletions stats/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@

class QuestionStatsTable(tables.Table):
question_id = tables.Column(
accessor=Accessor("question.id"),
verbose_name=_("ID"),
accessor=Accessor("question.id"),
linkify=lambda record: reverse("questions:detail_stats", kwargs={"pk": record.question.id}),
)
question = RichTextEllipsisColumn(
accessor=Accessor("question.text"), verbose_name=Question._meta.get_field("text").verbose_name
verbose_name=Question._meta.get_field("text").verbose_name, accessor=Accessor("question.text")
)
success_rate = tables.Column(
verbose_name=_("Successfully answered"), empty_values=(), order_by=("answer_success_count", "answer_count")
Expand All @@ -46,12 +46,12 @@ def render_success_rate(self, value, record):

class QuizStatsTable(tables.Table):
quiz_id = tables.Column(
accessor=Accessor("quiz.id"),
verbose_name=_("ID"),
accessor=Accessor("quiz.id"),
linkify=lambda record: reverse("quizs:detail_stats", kwargs={"pk": record.quiz.id}),
)
quiz = RichTextEllipsisColumn(
accessor=Accessor("quiz.name"), verbose_name=Quiz._meta.get_field("name").verbose_name
verbose_name=Quiz._meta.get_field("name").verbose_name, accessor=Accessor("quiz.name")
)
success_rate = tables.Column(
verbose_name=_("Successfully answered"),
Expand Down
7 changes: 4 additions & 3 deletions tags/tables.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import django_tables2 as tables
from django.db.models import Count
from django.utils.translation import gettext_lazy as _

from core.tables import DEFAULT_ATTRS, DEFAULT_TEMPLATE, RichTextColumn
from questions.models import Question
from quizs.models import Quiz
from tags.models import Tag


Expand All @@ -14,8 +15,8 @@
class TagTable(tables.Table):
id = tables.Column(linkify=lambda record: record.get_absolute_url())
description = RichTextColumn(attrs={"td": {"title": lambda record: record.description}})
question_count = tables.Column(verbose_name=_("Questions"))
quiz_count = tables.Column(verbose_name=_("Quizs"))
question_count = tables.Column(verbose_name=Question._meta.verbose_name_plural)
quiz_count = tables.Column(verbose_name=Quiz._meta.verbose_name_plural)

class Meta:
model = Tag
Expand Down
26 changes: 2 additions & 24 deletions templates/quizs/detail_questions.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{% extends "quizs/detail_base.html" %}
{% load render_table from django_tables2 %}
{% load i18n django_bootstrap5 %}

{% block extra_css %}
Expand All @@ -8,30 +9,7 @@
{% block quiz_detail_content %}
<div class="row">
<div class="col-12">
<div class="table-container">
<table class="table-responsive table-striped table-bordered border-primary font-size-small">
<thead>
<tr>
<th>ID</th>
<th>Question</th>
<th>Ordre</th>
<th>Visibilité</th>
</tr>
</thead>
<tbody>
{% for quiz_question in quiz_questions %}
<tr>
<td>
<a href="{% url 'questions:detail_view' quiz_question.question.id %}">{{ quiz_question.question.id }}</a>
</td>
<td>{{ quiz_question.question.text }}</td>
<td>{{ quiz_question.order }}</td>
<td>{{ quiz_question.question.visibility }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% render_table table %}
</div>
</div>

Expand Down
7 changes: 4 additions & 3 deletions users/tables.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import django_tables2 as tables
from django.utils.translation import gettext_lazy as _

from core.tables import DEFAULT_ATTRS, DEFAULT_TEMPLATE, ArrayColumn
from questions.models import Question
from quizs.models import Quiz
from users.models import User


class ContributorTable(tables.Table):
question_count = tables.Column(verbose_name=_("Questions"))
quiz_count = tables.Column(verbose_name=_("Quizs"))
question_count = tables.Column(verbose_name=Question._meta.verbose_name_plural)
quiz_count = tables.Column(verbose_name=Quiz._meta.verbose_name_plural)
roles = ArrayColumn()

class Meta:
Expand Down
30 changes: 20 additions & 10 deletions www/quizs/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from quizs.filters import QuizFilter
from quizs.forms import QUIZ_FORM_FIELDS, QuizCreateForm, QuizEditForm, QuizQuestionFormSet
from quizs.models import Quiz
from quizs.tables import QuizTable
from quizs.tables import QuizQuestionTable, QuizTable
from stats.models import QuizAggStat
from users import constants as user_constants

Expand Down Expand Up @@ -132,31 +132,41 @@ def get_success_url(self):
return reverse_lazy("quizs:detail_view", args=[self.kwargs.get("pk")])


class QuizDetailQuestionListView(ContributorUserRequiredMixin, FormView):
form_class = QuizQuestionFormSet
class QuizDetailQuestionListView(ContributorUserRequiredMixin, SingleTableMixin, FormView):
template_name = "quizs/detail_questions.html"
success_message = _("The quiz questions were updated.")
table_class = QuizQuestionTable
form_class = QuizQuestionFormSet

def get(self, request, *args, **kwargs):
self.quiz = Quiz.objects.get(id=self.kwargs.get("pk"))
return super().get(request, *args, **kwargs)

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["quiz"] = Quiz.objects.get(id=self.kwargs.get("pk"))
context["quiz_questions"] = context["quiz"].quizquestion_set.all()
context["user_can_edit"] = self.request.user.can_edit_quiz(context["quiz"])
context["quiz"] = self.quiz
context["quiz_questions"] = self.quiz.quizquestion_set.all()
context["user_can_edit"] = self.request.user.can_edit_quiz(self.quiz)
if self.request.POST and context["user_can_edit"]:
context["quiz_question_formset"] = QuizQuestionFormSet(self.request.POST, instance=context["quiz"])
context["quiz_question_formset"] = QuizQuestionFormSet(self.request.POST, instance=self.quiz)
else:
context["quiz_question_formset"] = QuizQuestionFormSet(instance=context["quiz"])
context["quiz_question_formset"] = QuizQuestionFormSet(instance=self.quiz)
return context

def get_table_data(self):
return self.quiz.quizquestion_set.all()
# return self.get_context_data()["quiz"].quizquestion_set.all()

def post(self, request, *args, **kwargs):
quiz_question_formset = QuizQuestionFormSet(self.request.POST, instance=self.get_context_data()["quiz"])
self.quiz = Quiz.objects.get(id=self.kwargs.get("pk"))
quiz_question_formset = QuizQuestionFormSet(self.request.POST, instance=self.quiz)
if quiz_question_formset.is_valid():
return self.form_valid(quiz_question_formset)
else:
return self.form_invalid(quiz_question_formset)

def form_valid(self, quiz_question_formset):
quiz_question_formset.instance = self.get_context_data()["quiz"]
quiz_question_formset.instance = self.quiz
quiz_question_formset.save()
messages.add_message(self.request, messages.SUCCESS, self.success_message)
return super().form_valid(quiz_question_formset)
Expand Down

0 comments on commit 1b6ad7a

Please sign in to comment.