From 8020bd9192cec91f9b2091295deef017e5c1c25e Mon Sep 17 00:00:00 2001 From: vincent porte Date: Tue, 1 Oct 2024 14:33:27 +0200 Subject: [PATCH 01/10] add DocumentRating model --- lacommunaute/documentation/admin.py | 10 ++++- lacommunaute/documentation/factories.py | 17 +++++++- .../migrations/0002_documentrating.py | 40 +++++++++++++++++++ lacommunaute/documentation/models.py | 16 ++++++++ 4 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 lacommunaute/documentation/migrations/0002_documentrating.py diff --git a/lacommunaute/documentation/admin.py b/lacommunaute/documentation/admin.py index c91b531c..d51d72ee 100644 --- a/lacommunaute/documentation/admin.py +++ b/lacommunaute/documentation/admin.py @@ -1,6 +1,6 @@ from django.contrib import admin -from lacommunaute.documentation.models import Category, Document +from lacommunaute.documentation.models import Category, Document, DocumentRating class DocumentInlines(admin.TabularInline): @@ -30,3 +30,11 @@ class DocumentAdmin(admin.ModelAdmin): list_filter = ("category", "partner") search_fields = ("name",) fields = ("name", "short_description", "description", "image", "category", "partner", "certified", "tags") + + +@admin.register(DocumentRating) +class DocumentRatingAdmin(admin.ModelAdmin): + list_display = ("document", "rating", "created") + list_filter = ("document",) + list_display_links = ("rating",) + raw_id_fields = ("document", "user") diff --git a/lacommunaute/documentation/factories.py b/lacommunaute/documentation/factories.py index d752dbd8..811662f4 100644 --- a/lacommunaute/documentation/factories.py +++ b/lacommunaute/documentation/factories.py @@ -1,7 +1,7 @@ import factory from faker import Faker -from lacommunaute.documentation.models import Category, Document +from lacommunaute.documentation.models import Category, Document, DocumentRating faker = Faker() @@ -46,3 +46,18 @@ def with_tags(self, create, extracted, **kwargs): if isinstance(extracted, list): for tag in extracted: self.tags.add(tag) + + +class DocumentRatingFactory(factory.django.DjangoModelFactory): + document = factory.SubFactory(DocumentFactory) + rating = factory.Faker("random_int", min=1, max=5) + + class Meta: + model = DocumentRating + skip_postgeneration_save = True + + @factory.post_generation + def set_created(self, create, extracted, **kwargs): + if extracted: + self.created = extracted + self.save() diff --git a/lacommunaute/documentation/migrations/0002_documentrating.py b/lacommunaute/documentation/migrations/0002_documentrating.py new file mode 100644 index 00000000..4f9983da --- /dev/null +++ b/lacommunaute/documentation/migrations/0002_documentrating.py @@ -0,0 +1,40 @@ +# Generated by Django 5.0.9 on 2024-10-01 10:02 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("documentation", "0001_initial"), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name="DocumentRating", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("created", models.DateTimeField(blank=True, null=True)), + ("updated", models.DateTimeField(blank=True, null=True)), + ("session_id", models.CharField(max_length=40)), + ("rating", models.PositiveSmallIntegerField()), + ( + "document", + models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to="documentation.document"), + ), + ( + "user", + models.ForeignKey( + blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL + ), + ), + ], + options={ + "verbose_name": "Notation d'un document", + "verbose_name_plural": "Notations des documents", + "ordering": ("-created",), + }, + ), + ] diff --git a/lacommunaute/documentation/models.py b/lacommunaute/documentation/models.py index fb3efaf8..7b8fe562 100644 --- a/lacommunaute/documentation/models.py +++ b/lacommunaute/documentation/models.py @@ -1,3 +1,4 @@ +from django.conf import settings from django.contrib.contenttypes.fields import GenericRelation from django.db import models from django.urls import reverse @@ -43,3 +44,18 @@ def get_absolute_url(self): return reverse( "documentation:document_detail", kwargs={"category_pk": self.category.pk, "pk": self.pk, "slug": self.slug} ) + + +# TODO : use AbstractDatedModel after ForumRating migration +class DocumentRating(models.Model): + created = models.DateTimeField(null=True, blank=True) + updated = models.DateTimeField(null=True, blank=True) + session_id = models.CharField(max_length=40) + document = models.ForeignKey(Document, on_delete=models.CASCADE) + rating = models.PositiveSmallIntegerField() + user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True, blank=True) + + class Meta: + verbose_name = "Notation d'un document" + verbose_name_plural = "Notations des documents" + ordering = ("-created",) From 8a5a3f70aac21a7b44c28f372828376e60a55dc4 Mon Sep 17 00:00:00 2001 From: vincent porte Date: Tue, 1 Oct 2024 14:34:08 +0200 Subject: [PATCH 02/10] add ForumRating migration into DocumentRating --- .../commands/migrate_documentation.py | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/lacommunaute/documentation/management/commands/migrate_documentation.py b/lacommunaute/documentation/management/commands/migrate_documentation.py index 05b5a8a2..f74952dd 100644 --- a/lacommunaute/documentation/management/commands/migrate_documentation.py +++ b/lacommunaute/documentation/management/commands/migrate_documentation.py @@ -4,8 +4,8 @@ from django.core.management.base import BaseCommand from taggit.models import TaggedItem -from lacommunaute.documentation.models import Category, Document -from lacommunaute.forum.models import Forum +from lacommunaute.documentation.models import Category, Document, DocumentRating +from lacommunaute.forum.models import Forum, ForumRating def create_categories_from_catforums(): @@ -52,6 +52,22 @@ def create_document_from_forums(category_transpo_dict): return transpo_dict +def migrate_ratings(document_transpo_dict): + document_ratings = [ + DocumentRating( + document=document_transpo_dict[rating.forum], + session_id=rating.session_id, + rating=rating.rating, + user=rating.user, + created=rating.created, + updated=rating.updated, + ) + for rating in ForumRating.objects.all() + ] + DocumentRating.objects.bulk_create(document_ratings) + ForumRating.objects.all().delete() + + def del_forums(category_transpo_dict, document_transpo_dict): forums_to_delete = list(category_transpo_dict.keys()) + list(document_transpo_dict.keys()) return Forum.objects.filter(pk__in=[forum.pk for forum in forums_to_delete]).delete() @@ -69,7 +85,10 @@ def handle(self, *args, **options): document_transpo_dict = create_document_from_forums(category_transpo_dict) sys.stdout.write("Documents created\n") - ## TODO next : migrate Ratings, Topics and Stats + migrate_ratings(document_transpo_dict) + sys.stdout.write("Ratings migrated\n") + + ## TODO next : Topics and Stats deleted_forums = del_forums(category_transpo_dict, document_transpo_dict) sys.stdout.write(f"{deleted_forums} forums deleted\n") From d355822cc3ef367df2e871b65265e6227333907c Mon Sep 17 00:00:00 2001 From: vincent porte Date: Tue, 1 Oct 2024 15:13:04 +0200 Subject: [PATCH 03/10] add ForumRatingView --- .../tests_document_detail_view.ambr | 132 ++++++++++++++++++ .../tests_document_rating_view.ambr | 97 +++++++++++++ .../tests/tests_document_rating_view.py | 63 +++++++++ lacommunaute/documentation/urls.py | 2 + lacommunaute/documentation/views.py | 29 +++- .../documentation/document_detail.html | 1 + .../documentation/partials/rating.html | 32 +++++ 7 files changed, 355 insertions(+), 1 deletion(-) create mode 100644 lacommunaute/documentation/tests/__snapshots__/tests_document_rating_view.ambr create mode 100644 lacommunaute/documentation/tests/tests_document_rating_view.py create mode 100644 lacommunaute/templates/documentation/partials/rating.html diff --git a/lacommunaute/documentation/tests/__snapshots__/tests_document_detail_view.ambr b/lacommunaute/documentation/tests/__snapshots__/tests_document_detail_view.ambr index b5e79514..7ab3ff03 100644 --- a/lacommunaute/documentation/tests/__snapshots__/tests_document_detail_view.ambr +++ b/lacommunaute/documentation/tests/__snapshots__/tests_document_detail_view.ambr @@ -64,6 +64,39 @@ +
+
+ +

Cette fiche vous a-t-elle été utile ?

+
+
+ + + + + + + + + + + +
+
+ +
+
+
@@ -166,6 +199,39 @@
+
+
+ +

Cette fiche vous a-t-elle été utile ?

+
+
+ + + + + + + + + + + +
+
+ +
+
+
@@ -273,6 +339,39 @@
+
+
+ +

Cette fiche vous a-t-elle été utile ?

+
+
+ + + + + + + + + + + +
+
+ +
+
+
@@ -370,6 +469,39 @@
+
+
+ +

Cette fiche vous a-t-elle été utile ?

+
+
+ + + + + + + + + + + +
+
+ +
+
+
diff --git a/lacommunaute/documentation/tests/__snapshots__/tests_document_rating_view.ambr b/lacommunaute/documentation/tests/__snapshots__/tests_document_rating_view.ambr new file mode 100644 index 00000000..693b80c0 --- /dev/null +++ b/lacommunaute/documentation/tests/__snapshots__/tests_document_rating_view.ambr @@ -0,0 +1,97 @@ +# serializer version: 1 +# name: test_post_rating[-user_post_document_rating][user_post_document_rating] + ''' +
+
+ +

Merci d'avoir noté cette fiche !

+
+
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+
1 avis, moyenne 5,00
+
+ +
+
+ + ''' +# --- +# name: test_post_rating[None-anonymous_post_document_rating][anonymous_post_document_rating] + ''' +
+
+ +

Merci d'avoir noté cette fiche !

+
+
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+
1 avis, moyenne 5,00
+
+ +
+
+ + ''' +# --- diff --git a/lacommunaute/documentation/tests/tests_document_rating_view.py b/lacommunaute/documentation/tests/tests_document_rating_view.py new file mode 100644 index 00000000..d1fe7b1a --- /dev/null +++ b/lacommunaute/documentation/tests/tests_document_rating_view.py @@ -0,0 +1,63 @@ +import pytest # noqa +from django.urls import reverse + +from lacommunaute.documentation.factories import DocumentFactory, DocumentRatingFactory +from lacommunaute.documentation.models import DocumentRating +from lacommunaute.users.factories import UserFactory +from lacommunaute.utils.testing import parse_response_to_soup + + +@pytest.fixture(name="document") +def fixture_document(db): + return DocumentFactory() + + +@pytest.fixture(name="url") +def fixture_url(document): + return reverse( + "documentation:document_rate", + kwargs={"category_pk": document.category.pk, "pk": document.pk, "slug": document.slug}, + ) + + +@pytest.mark.parametrize("method", ["get", "delete", "put", "patch", "head", "trace"]) +def test_forbidden_methods(url, client, method): + response = getattr(client, method)(url) + assert response.status_code == 405 + + +@pytest.mark.parametrize( + "user,expected_snapshot", + [(None, "anonymous_post_document_rating"), (lambda: UserFactory(), "user_post_document_rating")], +) +def test_post_rating(client, url, document, user, expected_snapshot, snapshot): + client.session.save() + if user: + user = user() + client.force_login(user) + + response = client.post(url, data={"rating": 5}) + assert response.status_code == 200 + content = parse_response_to_soup(response) + assert str(content) == snapshot(name=expected_snapshot) + + document_rating = DocumentRating.objects.get() + assert document_rating.document == document + if user: + assert document_rating.user == user + else: + assert document_rating.user is None + assert document_rating.rating == 5 + assert document_rating.session_id == client.session.session_key + + +def test_context_and_annotations(client, url, document): + DocumentRatingFactory.create_batch(3, document=document, rating=1) + DocumentRatingFactory.create_batch(2, document=document, rating=5) + client.force_login(UserFactory()) + + response = client.post(url, data={"rating": 5}) + assert response.status_code == 200 + assert response.context["count"] == 6 + assert response.context["average"] == 3 + assert response.context["rating"] == 5 diff --git a/lacommunaute/documentation/urls.py b/lacommunaute/documentation/urls.py index 717e37e5..4d793bbb 100644 --- a/lacommunaute/documentation/urls.py +++ b/lacommunaute/documentation/urls.py @@ -6,6 +6,7 @@ CategoryListView, CategoryUpdateView, DocumentDetailView, + DocumentRatingView, ) @@ -18,4 +19,5 @@ path("category/create/", CategoryCreateView.as_view(), name="category_create"), path("-/update/", CategoryUpdateView.as_view(), name="category_update"), path("/-/", DocumentDetailView.as_view(), name="document_detail"), + path("/-/rate/", DocumentRatingView.as_view(), name="document_rate"), ] diff --git a/lacommunaute/documentation/views.py b/lacommunaute/documentation/views.py index 748cbe0d..e4169fd8 100644 --- a/lacommunaute/documentation/views.py +++ b/lacommunaute/documentation/views.py @@ -1,11 +1,14 @@ from django.contrib.auth.mixins import UserPassesTestMixin from django.contrib.contenttypes.models import ContentType +from django.db.models import Avg, Count +from django.shortcuts import get_object_or_404, render from django.urls import reverse +from django.views import View from django.views.generic import DetailView, ListView from django.views.generic.edit import CreateView, UpdateView from taggit.models import Tag -from lacommunaute.documentation.models import Category, Document +from lacommunaute.documentation.models import Category, Document, DocumentRating class CategoryListView(ListView): @@ -87,3 +90,27 @@ def get_context_data(self, **kwargs): "back_url": self.object.get_absolute_url(), } return super().get_context_data(**kwargs) | additionnal_context + + +class DocumentRatingView(View): + def get_sum_and_mean_of_ratings(self): + return DocumentRating.objects.filter(document=self.kwargs["pk"]).aggregate( + count=Count("rating"), average=Avg("rating") + ) + + def post(self, request, *args, **kwargs): + document_rating = DocumentRating.objects.create( + document=get_object_or_404(Document, pk=self.kwargs["pk"]), + user=request.user if request.user.is_authenticated else None, + rating=int(request.POST["rating"]), + session_id=request.session.session_key, + ) + + return render( + request, + "documentation/partials/rating.html", + context={ + "rating": document_rating.rating, + **self.get_sum_and_mean_of_ratings(), + }, + ) diff --git a/lacommunaute/templates/documentation/document_detail.html b/lacommunaute/templates/documentation/document_detail.html index 4582fb88..32513b57 100644 --- a/lacommunaute/templates/documentation/document_detail.html +++ b/lacommunaute/templates/documentation/document_detail.html @@ -21,6 +21,7 @@ {% include "documentation/partials/partner.html" with partner=document.partner only %}
{% endif %} + {% include "documentation/partials/rating.html" with document=document only %}
diff --git a/lacommunaute/templates/documentation/partials/rating.html b/lacommunaute/templates/documentation/partials/rating.html new file mode 100644 index 00000000..2d530ac2 --- /dev/null +++ b/lacommunaute/templates/documentation/partials/rating.html @@ -0,0 +1,32 @@ +
+
+ {% if rating %} +

Merci d'avoir noté cette fiche !

+
+
+ {% for star in "12345" %} +
+ {% if forloop.counter > rating %} + + {% else %} + + {% endif %} +
+ {% endfor %} +
+
{{ count }} avis, moyenne {{ average|floatformat:2 }}
+
+ {% else %} +

Cette fiche vous a-t-elle été utile ?

+
+
+ {% for star in "12345" %} + + {% endfor %} +
+
+ {% endif %} +
+
From 6705541b021cf51515771c4c4f3fab8744b7b4b3 Mon Sep 17 00:00:00 2001 From: vincent porte Date: Tue, 1 Oct 2024 16:48:13 +0200 Subject: [PATCH 04/10] show ForumRating in DocumentDetailView, if rating exists for the document and a specified session key --- .../tests_document_detail_view.ambr | 47 ++++++++++++++ .../tests/tests_document_detail_view.py | 12 +++- lacommunaute/documentation/views.py | 65 ++++++++++++------- .../documentation/document_detail.html | 2 +- 4 files changed, 99 insertions(+), 27 deletions(-) diff --git a/lacommunaute/documentation/tests/__snapshots__/tests_document_detail_view.ambr b/lacommunaute/documentation/tests/__snapshots__/tests_document_detail_view.ambr index 7ab3ff03..5b34f33e 100644 --- a/lacommunaute/documentation/tests/__snapshots__/tests_document_detail_view.ambr +++ b/lacommunaute/documentation/tests/__snapshots__/tests_document_detail_view.ambr @@ -534,3 +534,50 @@ ''' # --- +# name: test_detail_view_with_rated_document[document_detail_view_with_rated_document] + ''' +
+
+ +

Merci d'avoir noté cette fiche !

+
+
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+
1 avis, moyenne 3,00
+
+ +
+
+ ''' +# --- diff --git a/lacommunaute/documentation/tests/tests_document_detail_view.py b/lacommunaute/documentation/tests/tests_document_detail_view.py index f1b3c62b..c66487f6 100644 --- a/lacommunaute/documentation/tests/tests_document_detail_view.py +++ b/lacommunaute/documentation/tests/tests_document_detail_view.py @@ -1,6 +1,6 @@ import pytest -from lacommunaute.documentation.factories import DocumentFactory +from lacommunaute.documentation.factories import DocumentFactory, DocumentRatingFactory from lacommunaute.partner.factories import PartnerFactory from lacommunaute.utils.testing import parse_response_to_soup # noqa @@ -53,3 +53,13 @@ def test_detail_view(client, db, document, snapshot, setup_func, snapshot_name): replace_current_date_format="%d/%m/%Y", ) assert str(content) == snapshot(name=snapshot_name) + + +def test_detail_view_with_rated_document(client, db, document, snapshot): + client.session.save() + DocumentRatingFactory(document=document, rating=3, session_id=client.session.session_key) + + response = client.get(document.get_absolute_url()) + assert response.status_code == 200 + content = parse_response_to_soup(response, selector="#rating-area") + assert str(content) == snapshot(name="document_detail_view_with_rated_document") diff --git a/lacommunaute/documentation/views.py b/lacommunaute/documentation/views.py index e4169fd8..ca4ab250 100644 --- a/lacommunaute/documentation/views.py +++ b/lacommunaute/documentation/views.py @@ -54,12 +54,51 @@ def get_context_data(self, **kwargs): return context -class DocumentDetailView(DetailView): +class RatingMixin: + def get_sum_and_mean_of_ratings(self, document): + return DocumentRating.objects.filter(document=document).aggregate(count=Count("rating"), average=Avg("rating")) + + def get_session_rating(self, document): + return getattr( + DocumentRating.objects.filter(document=document, session_id=self.request.session.session_key).first(), + "rating", + None, + ) + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context = context | { + "rating": self.get_session_rating(self.object), + **self.get_sum_and_mean_of_ratings(self.object), + } + return context + + +class DocumentDetailView(RatingMixin, DetailView): model = Document template_name = "documentation/document_detail.html" context_object_name = "document" +class DocumentRatingView(RatingMixin, View): + def post(self, request, *args, **kwargs): + document_rating = DocumentRating.objects.create( + document=get_object_or_404(Document, pk=self.kwargs["pk"]), + user=request.user if request.user.is_authenticated else None, + rating=int(request.POST["rating"]), + session_id=request.session.session_key, + ) + + return render( + request, + "documentation/partials/rating.html", + context={"rating": document_rating.rating, **self.get_sum_and_mean_of_ratings(document_rating.document)}, + ) + + +# CREATE AND UPDATE VIEWS + + class CreateUpdateMixin(UserPassesTestMixin): def test_func(self): return self.request.user.is_superuser @@ -90,27 +129,3 @@ def get_context_data(self, **kwargs): "back_url": self.object.get_absolute_url(), } return super().get_context_data(**kwargs) | additionnal_context - - -class DocumentRatingView(View): - def get_sum_and_mean_of_ratings(self): - return DocumentRating.objects.filter(document=self.kwargs["pk"]).aggregate( - count=Count("rating"), average=Avg("rating") - ) - - def post(self, request, *args, **kwargs): - document_rating = DocumentRating.objects.create( - document=get_object_or_404(Document, pk=self.kwargs["pk"]), - user=request.user if request.user.is_authenticated else None, - rating=int(request.POST["rating"]), - session_id=request.session.session_key, - ) - - return render( - request, - "documentation/partials/rating.html", - context={ - "rating": document_rating.rating, - **self.get_sum_and_mean_of_ratings(), - }, - ) diff --git a/lacommunaute/templates/documentation/document_detail.html b/lacommunaute/templates/documentation/document_detail.html index 32513b57..ec75af4c 100644 --- a/lacommunaute/templates/documentation/document_detail.html +++ b/lacommunaute/templates/documentation/document_detail.html @@ -21,7 +21,7 @@ {% include "documentation/partials/partner.html" with partner=document.partner only %}
{% endif %} - {% include "documentation/partials/rating.html" with document=document only %} + {% include "documentation/partials/rating.html" with document=document rating=rating count=count average=average only %}
From 7bb1a0e5544882f7dce63fffd2c5fc22b0ef5eb7 Mon Sep 17 00:00:00 2001 From: vincent porte Date: Tue, 1 Oct 2024 16:49:37 +0200 Subject: [PATCH 05/10] update ForumStatWeekArchiveView to display DocumentRating instead of ForumRating --- .../stats/tests/__snapshots__/tests_views.ambr | 4 ++-- lacommunaute/stats/tests/tests_views.py | 17 ++++++++++------- lacommunaute/stats/views.py | 12 +++++++----- .../stats/forum_stat_week_archive.html | 10 +++++----- 4 files changed, 24 insertions(+), 19 deletions(-) diff --git a/lacommunaute/stats/tests/__snapshots__/tests_views.ambr b/lacommunaute/stats/tests/__snapshots__/tests_views.ambr index da02eb74..80760e16 100644 --- a/lacommunaute/stats/tests/__snapshots__/tests_views.ambr +++ b/lacommunaute/stats/tests/__snapshots__/tests_views.ambr @@ -872,7 +872,7 @@ ''' # --- -# name: TestForumStatWeekArchiveView.test_most_rated_forums[most_rated_forums] +# name: TestForumStatWeekArchiveView.test_most_rated_documents[most_rated_documents] '''
@@ -891,7 +891,7 @@ - Forum A + Document A 2 3,00 diff --git a/lacommunaute/stats/tests/tests_views.py b/lacommunaute/stats/tests/tests_views.py index 0647a8d9..ffbd1ee4 100644 --- a/lacommunaute/stats/tests/tests_views.py +++ b/lacommunaute/stats/tests/tests_views.py @@ -12,6 +12,7 @@ from machina.core.loading import get_class from pytest_django.asserts import assertContains, assertNotContains +from lacommunaute.documentation.factories import DocumentFactory, DocumentRatingFactory from lacommunaute.forum.factories import CategoryForumFactory, ForumFactory, ForumRatingFactory from lacommunaute.stats.enums import Period from lacommunaute.stats.factories import ForumStatFactory, StatFactory @@ -361,23 +362,25 @@ def test_paginated_most_viewed_forums(self, client, db): assert response.status_code == 200 assert len(response.context_data["forum_stats"]) == 15 - def test_most_rated_forums(self, client, db, snapshot): + def test_most_rated_documents(self, client, db, snapshot): + # required to unblock the view, until ForumStat is migrated to the new model fs = ForumStatFactory(for_snapshot=True, forum__name="Forum A") + document = DocumentFactory(name="Document A") # rating within range - ForumRatingFactory.create_batch(2, rating=5, forum=fs.forum, set_created=fs.date) + DocumentRatingFactory.create_batch(2, rating=5, document=document, set_created=fs.date) # rating out of range - ForumRatingFactory.create_batch(2, rating=1, forum=fs.forum) + DocumentRatingFactory.create_batch(2, rating=1, document=document) - # undesired forum - ForumFactory() + # undesired document + DocumentFactory() # undesired rating - ForumRatingFactory(rating=4) + DocumentRatingFactory(rating=4) response = client.get(self.get_url_from_date(fs.date)) assert response.status_code == 200 - assert str(parse_response_to_soup(response, selector="#most_rated")) == snapshot(name="most_rated_forums") + assert str(parse_response_to_soup(response, selector="#most_rated")) == snapshot(name="most_rated_documents") def test_visitors(self, client, db, snapshot): fs = ForumStatFactory(for_snapshot=True) diff --git a/lacommunaute/stats/views.py b/lacommunaute/stats/views.py index 2ab04c70..8f0d5e89 100644 --- a/lacommunaute/stats/views.py +++ b/lacommunaute/stats/views.py @@ -12,6 +12,7 @@ from django.views.generic.base import TemplateView from django.views.generic.dates import WeekArchiveView +from lacommunaute.documentation.models import Document from lacommunaute.forum.models import Forum, ForumRating from lacommunaute.stats.models import ForumStat, Stat from lacommunaute.surveys.models import DSP @@ -140,15 +141,16 @@ def get_dates_of_the_week(self): start_date = datetime.date(self.get_year(), 1, 1) + datetime.timedelta(weeks=self.get_week() - 1) return start_date, start_date + datetime.timedelta(days=6) - def get_most_rated_forums(self, start_date, end_date): + def get_most_rated_documents(self, start_date, end_date): return ( - Forum.objects.annotate(avg_rating=Avg("forumrating__rating")) + Document.objects.annotate(avg_rating=Avg("documentrating__rating")) .filter(avg_rating__isnull=False) .annotate( rating_count=Count( - "forumrating", + "documentrating", filter=Q( - forumrating__created__gte=start_date, forumrating__created__lt=end_date + relativedelta(days=1) + documentrating__created__gte=start_date, + documentrating__created__lt=end_date + relativedelta(days=1), ), ) ) @@ -161,7 +163,7 @@ def get_context_data(self, **kwargs): start_date, end_date = self.get_dates_of_the_week() context["end_date"] = end_date context["stats"] = get_daily_visits_stats(from_date=end_date - relativedelta(days=89), to_date=end_date) - context["rated_forums"] = self.get_most_rated_forums(start_date, end_date) + context["rated_documents"] = self.get_most_rated_documents(start_date, end_date) return context diff --git a/lacommunaute/templates/stats/forum_stat_week_archive.html b/lacommunaute/templates/stats/forum_stat_week_archive.html index 8a922655..9dcc4709 100644 --- a/lacommunaute/templates/stats/forum_stat_week_archive.html +++ b/lacommunaute/templates/stats/forum_stat_week_archive.html @@ -68,7 +68,7 @@

- Les {{ rated_forums|length }} fiches pratiques les plus notées pendant la semaine du {{ week|date:"j F Y" }} au {{ end_date|date:"j F Y" }} + Les {{ rated_documents|length }} fiches pratiques les plus notées pendant la semaine du {{ week|date:"j F Y" }} au {{ end_date|date:"j F Y" }}

@@ -79,11 +79,11 @@

- {% for forum in rated_forums %} + {% for document in rated_documents %} - - - + + + {% endfor %} From 5634e8be10bca083bd3af311f498ee9b0b3325e2 Mon Sep 17 00:00:00 2001 From: vincent porte Date: Tue, 1 Oct 2024 14:32:54 +0200 Subject: [PATCH 06/10] remove ForumRatingView --- .../forum/tests/test_forum_rating_view.py | 56 ---------------- lacommunaute/forum/tests/tests_views.py | 22 +------ lacommunaute/forum/urls.py | 2 - lacommunaute/forum/views.py | 20 +----- .../templates/forum/forum_documentation.html | 1 - .../templates/forum/partials/rating.html | 65 ------------------- 6 files changed, 2 insertions(+), 164 deletions(-) delete mode 100644 lacommunaute/forum/tests/test_forum_rating_view.py delete mode 100644 lacommunaute/templates/forum/partials/rating.html diff --git a/lacommunaute/forum/tests/test_forum_rating_view.py b/lacommunaute/forum/tests/test_forum_rating_view.py deleted file mode 100644 index 7a7562d6..00000000 --- a/lacommunaute/forum/tests/test_forum_rating_view.py +++ /dev/null @@ -1,56 +0,0 @@ -import pytest # noqa -from django.urls import reverse - -from lacommunaute.forum.factories import ForumFactory -from lacommunaute.forum.models import ForumRating -from lacommunaute.users.factories import UserFactory -from lacommunaute.utils.testing import parse_response_to_soup - - -@pytest.fixture(name="public_forum") -def fixture_public_forum(db): - return ForumFactory(with_public_perms=True) - - -def test_get_forum_rating_view(client, db, public_forum): - response = client.get(reverse("forum_extension:rate", kwargs={"pk": public_forum.pk, "slug": public_forum.slug})) - assert response.status_code == 405 - - -def test_anonymous_post_forum_rating_view(client, db, public_forum, snapshot): - client.session.save() - - response = client.post( - reverse("forum_extension:rate", kwargs={"pk": public_forum.pk, "slug": public_forum.slug}), - data={"rating": "5"}, - ) - assert response.status_code == 200 - assert response.context["forum"] == public_forum - assert response.context["rating"] == 5 - content = parse_response_to_soup(response, replace_in_href=[public_forum]) - assert str(content) == snapshot(name="anonymous_post_forum_rating_view") - - forum_rating = ForumRating.objects.get() - assert forum_rating.forum == public_forum - assert forum_rating.user is None - assert forum_rating.rating == 5 - assert forum_rating.session_id == client.session.session_key - - -def test_authenticated_post_forum_rating_view(client, db, public_forum, snapshot): - user = UserFactory() - client.force_login(user) - - response = client.post( - reverse("forum_extension:rate", kwargs={"pk": public_forum.pk, "slug": public_forum.slug}), - data={"rating": "1"}, - ) - assert response.status_code == 200 - content = parse_response_to_soup(response, replace_in_href=[public_forum]) - assert str(content) == snapshot(name="authenticated_post_forum_rating_view") - - forum_rating = ForumRating.objects.get() - assert forum_rating.forum == public_forum - assert forum_rating.user == user - assert forum_rating.rating == 1 - assert forum_rating.session_id == client.session.session_key diff --git a/lacommunaute/forum/tests/tests_views.py b/lacommunaute/forum/tests/tests_views.py index c457a878..fa45a56e 100644 --- a/lacommunaute/forum/tests/tests_views.py +++ b/lacommunaute/forum/tests/tests_views.py @@ -11,7 +11,7 @@ from pytest_django.asserts import assertContains from taggit.models import Tag -from lacommunaute.forum.factories import CategoryForumFactory, ForumFactory, ForumRatingFactory +from lacommunaute.forum.factories import CategoryForumFactory, ForumFactory from lacommunaute.forum.models import Forum from lacommunaute.forum.views import ForumView from lacommunaute.forum_conversation.enums import Filters @@ -389,26 +389,6 @@ def test_banner_display_on_subcategory_forum(self): class TestForumViewContent: - def test_not_rated_forum(self, client, db, snapshot): - category_forum = CategoryForumFactory(with_public_perms=True, with_child=True, name="B Category") - forum = category_forum.get_children().first() - - response = client.get(reverse("forum_extension:forum", kwargs={"pk": forum.pk, "slug": forum.slug})) - assert response.status_code == 200 - content = parse_response_to_soup(response, selector="#rating-area1", replace_in_href=[category_forum, forum]) - assert str(content) == snapshot(name="not_rated_forum") - - def test_rated_forum(self, client, db, snapshot): - client.session.save() - category_forum = CategoryForumFactory(with_public_perms=True, with_child=True) - forum = category_forum.get_children().first() - ForumRatingFactory(forum=forum, rating=5, session_id=client.session.session_key) - - response = client.get(reverse("forum_extension:forum", kwargs={"pk": forum.pk, "slug": forum.slug})) - assert response.status_code == 200 - content = parse_response_to_soup(response, selector="#rating-area1") - assert str(content) == snapshot(name="rated_forum") - def test_opengraph_for_forum_with_image(self, client, db): forum = ForumFactory(with_public_perms=True, with_image=True) response = client.get(forum.get_absolute_url()) diff --git a/lacommunaute/forum/urls.py b/lacommunaute/forum/urls.py index b0427a9d..6c601566 100644 --- a/lacommunaute/forum/urls.py +++ b/lacommunaute/forum/urls.py @@ -2,7 +2,6 @@ from machina.apps.forum.views import IndexView from lacommunaute.forum.views import ( - ForumRatingView, ForumUpdateView, ForumView, SubCategoryForumListView, @@ -15,7 +14,6 @@ urlpatterns = [ path("forum/-/", ForumView.as_view(), name="forum"), path("forum/-/update/", ForumUpdateView.as_view(), name="edit_forum"), - path("forum/-/rate/", ForumRatingView.as_view(), name="rate"), path("forum/-/subs/", SubCategoryForumListView.as_view(), name="subcategory_forums"), path("forums/", IndexView.as_view(), name="index"), ] diff --git a/lacommunaute/forum/views.py b/lacommunaute/forum/views.py index 3b11e172..10f258b8 100644 --- a/lacommunaute/forum/views.py +++ b/lacommunaute/forum/views.py @@ -3,16 +3,14 @@ from django.conf import settings from django.contrib.auth.mixins import UserPassesTestMixin from django.contrib.contenttypes.models import ContentType -from django.shortcuts import get_object_or_404, render from django.urls import reverse -from django.views import View from django.views.generic import UpdateView from machina.apps.forum.views import ForumView as BaseForumView from machina.core.loading import get_class from taggit.models import Tag from lacommunaute.forum.forms import ForumForm -from lacommunaute.forum.models import Forum, ForumRating +from lacommunaute.forum.models import Forum from lacommunaute.forum_conversation.forms import PostForm from lacommunaute.forum_conversation.view_mixins import FilteredTopicsListViewMixin from lacommunaute.forum_upvote.models import UpVote @@ -131,19 +129,3 @@ def get_context_data(self, **kwargs): context["title"] = f"Mettre à jour le forum {self.object.name}" context["back_url"] = reverse("forum_extension:forum", kwargs={"pk": self.object.pk, "slug": self.object.slug}) return context - - -class ForumRatingView(View): - def post(self, request, *args, **kwargs): - forum_rating = ForumRating.objects.create( - forum=get_object_or_404(Forum, pk=self.kwargs["pk"]), - user=request.user if request.user.is_authenticated else None, - rating=int(request.POST["rating"]), - session_id=request.session.session_key, - ) - - return render( - request, - "forum/partials/rating.html", - context={"forum": forum_rating.forum, "rating": forum_rating.rating}, - ) diff --git a/lacommunaute/templates/forum/forum_documentation.html b/lacommunaute/templates/forum/forum_documentation.html index 07068385..bf4f3f5e 100644 --- a/lacommunaute/templates/forum/forum_documentation.html +++ b/lacommunaute/templates/forum/forum_documentation.html @@ -34,7 +34,6 @@ {% include "forum/partials/partner.html" with partner=forum.partner only %} {% endif %} - {% include "forum/partials/rating.html" with forum=forum rating_area_id="1" %}
diff --git a/lacommunaute/templates/forum/partials/rating.html b/lacommunaute/templates/forum/partials/rating.html deleted file mode 100644 index 7df033f5..00000000 --- a/lacommunaute/templates/forum/partials/rating.html +++ /dev/null @@ -1,65 +0,0 @@ -{% if onSidebar %} - -{% else %} - -{% endif %} From db86ded0fffec9522d420be4ae1c03297a6777a3 Mon Sep 17 00:00:00 2001 From: vincent porte Date: Tue, 1 Oct 2024 15:32:19 +0200 Subject: [PATCH 07/10] remove ForumRatingFactory --- lacommunaute/forum/factories.py | 17 +---------------- lacommunaute/forum/models.py | 1 + 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/lacommunaute/forum/factories.py b/lacommunaute/forum/factories.py index 668a2978..a6714858 100644 --- a/lacommunaute/forum/factories.py +++ b/lacommunaute/forum/factories.py @@ -1,7 +1,7 @@ import factory from machina.test.factories.forum import ForumFactory as BaseForumFactory -from lacommunaute.forum.models import Forum, ForumRating +from lacommunaute.forum.models import Forum from lacommunaute.forum_upvote.models import UpVote from lacommunaute.utils.perms import add_public_perms_on_forum @@ -64,18 +64,3 @@ def with_child(self, create, extracted, **kwargs): return ForumFactory(parent=self, with_public_perms=True, with_image=True, name=f"{self.name} - Forum") - - -class ForumRatingFactory(factory.django.DjangoModelFactory): - forum = factory.SubFactory(ForumFactory) - rating = factory.Faker("random_int", min=1, max=5) - - class Meta: - model = ForumRating - skip_postgeneration_save = True - - @factory.post_generation - def set_created(self, create, extracted, **kwargs): - if extracted: - self.created = extracted - self.save() diff --git a/lacommunaute/forum/models.py b/lacommunaute/forum/models.py index 8ac4fcf6..ca4f1123 100644 --- a/lacommunaute/forum/models.py +++ b/lacommunaute/forum/models.py @@ -72,6 +72,7 @@ def get_average_rating(self): return ForumRating.objects.filter(forum=self).aggregate(models.Avg("rating"))["rating__avg"] +# TODO : to be removed after migration class ForumRating(DatedModel): session_id = models.CharField(max_length=40) forum = models.ForeignKey(Forum, on_delete=models.CASCADE) From 557d68d3d38c0a0a12490c2fd63763870962b7cb Mon Sep 17 00:00:00 2001 From: vincent porte Date: Tue, 1 Oct 2024 16:48:49 +0200 Subject: [PATCH 08/10] remove unusefull property on Forum model, related to ForumRating --- lacommunaute/forum/models.py | 6 ------ lacommunaute/forum/tests/tests_model.py | 19 +------------------ lacommunaute/forum/tests/tests_views.py | 6 +++--- lacommunaute/forum/views.py | 2 -- 4 files changed, 4 insertions(+), 29 deletions(-) diff --git a/lacommunaute/forum/models.py b/lacommunaute/forum/models.py index ca4f1123..d68fa15e 100644 --- a/lacommunaute/forum/models.py +++ b/lacommunaute/forum/models.py @@ -65,12 +65,6 @@ def is_in_documentation_area(self): def is_toplevel_discussion_area(self): return self == Forum.objects.get_main_forum() - def get_session_rating(self, session_key): - return getattr(ForumRating.objects.filter(forum=self, session_id=session_key).first(), "rating", None) - - def get_average_rating(self): - return ForumRating.objects.filter(forum=self).aggregate(models.Avg("rating"))["rating__avg"] - # TODO : to be removed after migration class ForumRating(DatedModel): diff --git a/lacommunaute/forum/tests/tests_model.py b/lacommunaute/forum/tests/tests_model.py index dcd0a13a..33aeaca6 100644 --- a/lacommunaute/forum/tests/tests_model.py +++ b/lacommunaute/forum/tests/tests_model.py @@ -1,7 +1,7 @@ from django.conf import settings from django.test import TestCase -from lacommunaute.forum.factories import CategoryForumFactory, ForumFactory, ForumRatingFactory +from lacommunaute.forum.factories import CategoryForumFactory, ForumFactory from lacommunaute.forum.models import Forum from lacommunaute.forum_conversation.factories import TopicFactory from lacommunaute.users.factories import UserFactory @@ -72,23 +72,6 @@ def test_is_toplevel_discussion_area(self): self.assertFalse(forum.is_toplevel_discussion_area) self.assertFalse(sub_forum.is_toplevel_discussion_area) - def test_get_session_rating(self): - forum = ForumFactory() - forum_rating = ForumRatingFactory(forum=forum) - - self.assertIsNone(forum.get_session_rating("test")) - self.assertEqual(forum.get_session_rating(forum_rating.session_id), forum_rating.rating) - - ForumRatingFactory(forum=forum, session_id=forum_rating.session_id, rating=forum_rating.rating + 1) - self.assertEqual(forum.get_session_rating(forum_rating.session_id), forum_rating.rating + 1) - - def test_get_average_rating(self): - forum = ForumFactory() - ForumRatingFactory(forum=forum, rating=1) - ForumRatingFactory(forum=forum, rating=5) - - self.assertEqual(forum.get_average_rating(), 3) - class TestForumQueryset: def test_get_main_forum_wo_forum(self, db): diff --git a/lacommunaute/forum/tests/tests_views.py b/lacommunaute/forum/tests/tests_views.py index fa45a56e..d8fedd43 100644 --- a/lacommunaute/forum/tests/tests_views.py +++ b/lacommunaute/forum/tests/tests_views.py @@ -193,7 +193,7 @@ def test_queries(self): TopicFactory.create_batch(20, with_post=True) self.client.force_login(self.user) - with self.assertNumQueries(23): + with self.assertNumQueries(22): self.client.get(self.url) def test_certified_post_display(self): @@ -335,7 +335,7 @@ def test_filtered_queryset_on_tag(self): tag = faker.word() topic = TopicFactory(forum=self.forum, with_tags=[tag], with_post=True) - with self.assertNumQueries(20): + with self.assertNumQueries(19): response = self.client.get( reverse("forum_extension:forum", kwargs={"pk": self.forum.pk, "slug": self.forum.slug}), {"tag": tag} ) @@ -653,7 +653,7 @@ def test_numqueries_on_tags(self, client, db, django_assert_num_queries): 20, parent=category_forum, with_public_perms=True, with_tags=[f"tag{i}" for i in range(3)] ) # vincentporte TOBEFIXED : DUPLICATED QUERIES - with django_assert_num_queries(19): + with django_assert_num_queries(18): client.get(category_forum.get_absolute_url()) diff --git a/lacommunaute/forum/views.py b/lacommunaute/forum/views.py index 10f258b8..306ab8c7 100644 --- a/lacommunaute/forum/views.py +++ b/lacommunaute/forum/views.py @@ -88,8 +88,6 @@ def get_context_data(self, **kwargs): context["loadmoretopic_suffix"] = "topicsinforum" context["form"] = PostForm(forum=forum, user=self.request.user) - context["rating"] = forum.get_session_rating(self.request.session.session_key) - context["filter_dropdown_endpoint"] = ( None if self.request.GET.get("page") From dfefbaf2c9c931430438354cf5815296df05cf94 Mon Sep 17 00:00:00 2001 From: vincent porte Date: Wed, 9 Oct 2024 15:58:06 +0200 Subject: [PATCH 09/10] fixup! remove unusefull property on Forum model, related to ForumRating --- lacommunaute/forum/tests/tests_views.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lacommunaute/forum/tests/tests_views.py b/lacommunaute/forum/tests/tests_views.py index d8fedd43..8feb156c 100644 --- a/lacommunaute/forum/tests/tests_views.py +++ b/lacommunaute/forum/tests/tests_views.py @@ -82,7 +82,6 @@ def test_context(self): self.assertEqual(response.context_data["filters"], Filters.choices) self.assertEqual(response.context_data["loadmoretopic_url"], loadmoretopic_url) self.assertEqual(response.context_data["forum"], self.forum) - self.assertIsNone(response.context_data["rating"]) self.assertEqual(response.context_data["active_filter"], Filters.ALL) self.assertEqual(list(response.context_data["active_tag"]), []) From 72ffac5c2f4bdbef9b6b5b421accd28b84ec8bc3 Mon Sep 17 00:00:00 2001 From: vincent porte Date: Thu, 10 Oct 2024 12:17:11 +0200 Subject: [PATCH 10/10] update DocumentStatView, deactivate ForumStats queries until migration is coded in upcoming PR --- .../tests/__snapshots__/tests_views.ambr | 270 ++++++++++++++---- lacommunaute/stats/tests/tests_views.py | 37 +-- lacommunaute/stats/views.py | 20 +- 3 files changed, 238 insertions(+), 89 deletions(-) diff --git a/lacommunaute/stats/tests/__snapshots__/tests_views.ambr b/lacommunaute/stats/tests/__snapshots__/tests_views.ambr index 80760e16..ff0cc8b2 100644 --- a/lacommunaute/stats/tests/__snapshots__/tests_views.ambr +++ b/lacommunaute/stats/tests/__snapshots__/tests_views.ambr @@ -96,8 +96,8 @@
-
- + + @@ -108,8 +108,8 @@
- - + + @@ -120,8 +120,8 @@
- - + + @@ -132,12 +132,36 @@
- - + + + + + + + + + + + + + + + + + +
{{ forum.name }}{{ forum.rating_count }}{{ forum.avg_rating|floatformat:2 }}{{ document.name }}{{ document.rating_count }}{{ document.avg_rating|floatformat:2 }}
0h 40min700h 00min0 2 4,00
0h 30min1000h 00min0 1 3,00
0h 20min900h 00min0 4 2,00
0h 10min800h 00min0 3 5,00
+ Document wo DocumentStats +
+ +
0h 00min0pas de notation
+ Orphelin Document +
+ +
0h 00min0pas de notation
@@ -229,14 +253,38 @@ + + + Orphelin Document +
+ + + 0h 00min + 0 + pas de notation + + + + + + Document wo DocumentStats +
+ + + 0h 00min + 0 + pas de notation + + + D
- 0h 10min - 80 + 0h 00min + 0 3 5,00 @@ -247,8 +295,8 @@
- 0h 40min - 70 + 0h 00min + 0 2 4,00 @@ -259,8 +307,8 @@
- 0h 30min - 100 + 0h 00min + 0 1 3,00 @@ -271,8 +319,8 @@
- 0h 20min - 90 + 0h 00min + 0 4 2,00 @@ -368,14 +416,38 @@ + + + Orphelin Document +
+ + + 0h 00min + 0 + pas de notation + + + + + + Document wo DocumentStats +
+ + + 0h 00min + 0 + pas de notation + + + C
- 0h 20min - 90 + 0h 00min + 0 4 2,00 @@ -386,8 +458,8 @@
- 0h 10min - 80 + 0h 00min + 0 3 5,00 @@ -398,8 +470,8 @@
- 0h 40min - 70 + 0h 00min + 0 2 4,00 @@ -410,8 +482,8 @@
- 0h 30min - 100 + 0h 00min + 0 1 3,00 @@ -509,26 +581,26 @@ - A + Document wo DocumentStats
- 0h 40min - 70 - 2 - 4,00 + 0h 00min + 0 + pas de notation + - B + D
- 0h 30min - 100 - 1 - 3,00 + 0h 00min + 0 + 3 + 5,00 @@ -537,22 +609,46 @@
- 0h 20min - 90 + 0h 00min + 0 4 2,00 - D + B
- 0h 10min - 80 - 3 - 5,00 + 0h 00min + 0 + 1 + 3,00 + + + + + A +
+ + + 0h 00min + 0 + 2 + 4,00 + + + + + Orphelin Document +
+ + + 0h 00min + 0 + pas de notation + @@ -648,14 +744,26 @@ - B + Document wo DocumentStats
- 0h 30min - 100 - 1 - 3,00 + 0h 00min + 0 + pas de notation + + + + + + D +
+ + + 0h 00min + 0 + 3 + 5,00 @@ -664,22 +772,22 @@
- 0h 20min - 90 + 0h 00min + 0 4 2,00 - D + B
- 0h 10min - 80 - 3 - 5,00 + 0h 00min + 0 + 1 + 3,00 @@ -688,12 +796,24 @@
- 0h 40min - 70 + 0h 00min + 0 2 4,00 + + + Orphelin Document +
+ + + 0h 00min + 0 + pas de notation + + +
@@ -791,8 +911,8 @@
- 0h 40min - 70 + 0h 00min + 0 2 4,00 @@ -803,8 +923,8 @@
- 0h 30min - 100 + 0h 00min + 0 1 3,00 @@ -815,8 +935,8 @@
- 0h 20min - 90 + 0h 00min + 0 4 2,00 @@ -827,12 +947,36 @@
- 0h 10min - 80 + 0h 00min + 0 3 5,00 + + + Orphelin Document +
+ + + 0h 00min + 0 + pas de notation + + + + + + Document wo DocumentStats +
+ + + 0h 00min + 0 + pas de notation + + +

diff --git a/lacommunaute/stats/tests/tests_views.py b/lacommunaute/stats/tests/tests_views.py index ffbd1ee4..ebaa359a 100644 --- a/lacommunaute/stats/tests/tests_views.py +++ b/lacommunaute/stats/tests/tests_views.py @@ -12,8 +12,7 @@ from machina.core.loading import get_class from pytest_django.asserts import assertContains, assertNotContains -from lacommunaute.documentation.factories import DocumentFactory, DocumentRatingFactory -from lacommunaute.forum.factories import CategoryForumFactory, ForumFactory, ForumRatingFactory +from lacommunaute.documentation.factories import CategoryFactory, DocumentFactory, DocumentRatingFactory from lacommunaute.stats.enums import Period from lacommunaute.stats.factories import ForumStatFactory, StatFactory from lacommunaute.surveys.factories import DSPFactory @@ -257,23 +256,23 @@ def test_navigation(self, client, db, snapshot): @pytest.fixture(name="document_stats_setup") def document_stats_setup_fixture(db): - category = CategoryForumFactory() - fa = ForumFactory(name="A", parent=category) - fb = ForumFactory(name="B", parent=category) - fc = ForumFactory(name="C", parent=category) - fd = ForumFactory(name="D", parent=category) - ForumStatFactory(forum=fa, period="week", visits=70, time_spent=40 * 60) - ForumStatFactory(forum=fb, period="week", visits=100, time_spent=30 * 60) - ForumStatFactory(forum=fc, period="week", visits=90, time_spent=20 * 60) - ForumStatFactory(forum=fd, period="week", visits=80, time_spent=10 * 60) - ForumRatingFactory.create_batch(2, forum=fa, rating=4) - ForumRatingFactory.create_batch(1, forum=fb, rating=3) - ForumRatingFactory.create_batch(4, forum=fc, rating=2) - ForumRatingFactory.create_batch(3, forum=fd, rating=5) + category = CategoryFactory() + fa = DocumentFactory(name="A", category=category) + fb = DocumentFactory(name="B", category=category) + fc = DocumentFactory(name="C", category=category) + fd = DocumentFactory(name="D", category=category) + # ForumStatFactory(forum=fa, period="week", visits=70, time_spent=40 * 60) + # ForumStatFactory(forum=fb, period="week", visits=100, time_spent=30 * 60) + # ForumStatFactory(forum=fc, period="week", visits=90, time_spent=20 * 60) + # ForumStatFactory(forum=fd, period="week", visits=80, time_spent=10 * 60) + DocumentRatingFactory.create_batch(2, document=fa, rating=4) + DocumentRatingFactory.create_batch(1, document=fb, rating=3) + DocumentRatingFactory.create_batch(4, document=fc, rating=2) + DocumentRatingFactory.create_batch(3, document=fd, rating=5) # undesired forum - ForumFactory(name="Forum not in Document area") - ForumFactory(name="Forum wo ForumStats", parent=category) + DocumentFactory(name="Orphelin Document") + DocumentFactory(name="Document wo DocumentStats", category=category) return category @@ -296,7 +295,9 @@ def test_sort_key(self, client, db, document_stats_setup, sort_key, snapshot_nam assert response.status_code == 200 assert str( parse_response_to_soup( - response, selector="main", replace_in_href=[forum for forum in document_stats_setup.get_children()] + response, + selector="main", + replace_in_href=[document for document in document_stats_setup.documents.all()], ) ) == snapshot(name=snapshot_name) diff --git a/lacommunaute/stats/views.py b/lacommunaute/stats/views.py index 8f0d5e89..0fe8e1b9 100644 --- a/lacommunaute/stats/views.py +++ b/lacommunaute/stats/views.py @@ -2,7 +2,7 @@ import logging from dateutil.relativedelta import relativedelta -from django.db.models import Avg, CharField, Count, OuterRef, Q, Subquery, Sum +from django.db.models import Avg, CharField, Count, OuterRef, Q, Subquery, Value from django.db.models.functions import Cast from django.shortcuts import redirect, render from django.urls import reverse @@ -12,8 +12,7 @@ from django.views.generic.base import TemplateView from django.views.generic.dates import WeekArchiveView -from lacommunaute.documentation.models import Document -from lacommunaute.forum.models import Forum, ForumRating +from lacommunaute.documentation.models import Document, DocumentRating from lacommunaute.stats.models import ForumStat, Stat from lacommunaute.surveys.models import DSP from lacommunaute.utils.json import extract_values_in_list @@ -168,15 +167,20 @@ def get_context_data(self, **kwargs): class DocumentStatsView(View): + # MIGRATION : + # deactivate lines regarding ForumStat until this model is migrated into DocumentStat in later PR def get_objects_with_stats_and_ratings(self): objects = ( - Forum.objects.filter(parent__type=Forum.FORUM_CAT, forumstat__period="week") - .annotate(sum_visits=Sum("forumstat__visits")) - .annotate(sum_time_spent=Sum("forumstat__time_spent")) - .select_related("parent", "partner") + Document.objects.all() + # .filter(forumstat__period="week") + # .annotate(sum_visits=Sum("forumstat__visits")) + # .annotate(sum_time_spent=Sum("forumstat__time_spent")) + .annotate(sum_visits=Value(0)) + .annotate(sum_time_spent=Value(0)) + .select_related("category", "partner") .order_by("id") ) - ratings = ForumRating.objects.filter(forum=OuterRef("pk")).values("forum") + ratings = DocumentRating.objects.filter(document=OuterRef("pk")).values("document") return objects.annotate( avg_rating=Subquery(ratings.annotate(avg_rating=Avg("rating")).values("avg_rating")), count_rating=Subquery(ratings.annotate(count_rating=Count("rating")).values("count_rating")),