Séparation des vues catégorisation
This commit is contained in:
parent
897d8c6ea9
commit
5000efc353
@ -17,6 +17,12 @@ from .sitemaps import (
|
|||||||
)
|
)
|
||||||
from .models import Event, Place, Organisation, Category
|
from .models import Event, Place, Organisation, Category
|
||||||
from .views import (
|
from .views import (
|
||||||
|
# Categorisation rules
|
||||||
|
CategorisationRuleCreateView,
|
||||||
|
CategorisationRuleDeleteView,
|
||||||
|
CategorisationRuleUpdateView,
|
||||||
|
apply_categorisation_rules,
|
||||||
|
categorisation_rules,
|
||||||
# Errors
|
# Errors
|
||||||
internal_server_error,
|
internal_server_error,
|
||||||
page_not_found,
|
page_not_found,
|
||||||
@ -84,7 +90,6 @@ from .views import (
|
|||||||
RecurrentImportDeleteView,
|
RecurrentImportDeleteView,
|
||||||
RecurrentImportUpdateView,
|
RecurrentImportUpdateView,
|
||||||
run_rimport,
|
run_rimport,
|
||||||
categorisation_rules,
|
|
||||||
duplicates,
|
duplicates,
|
||||||
DuplicatedEventsDetailView,
|
DuplicatedEventsDetailView,
|
||||||
StaticContentCreateView,
|
StaticContentCreateView,
|
||||||
@ -108,10 +113,6 @@ from .views import (
|
|||||||
statistics,
|
statistics,
|
||||||
view_rimport,
|
view_rimport,
|
||||||
update_duplicate_event,
|
update_duplicate_event,
|
||||||
CategorisationRuleCreateView,
|
|
||||||
CategorisationRuleDeleteView,
|
|
||||||
CategorisationRuleUpdateView,
|
|
||||||
apply_categorisation_rules,
|
|
||||||
UserProfileUpdateView,
|
UserProfileUpdateView,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -143,6 +144,24 @@ sitemaps = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
# Categorisation rules
|
||||||
|
path(
|
||||||
|
"catrules/add",
|
||||||
|
CategorisationRuleCreateView.as_view(),
|
||||||
|
name="add_catrule",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"catrules/<int:pk>/delete",
|
||||||
|
CategorisationRuleDeleteView.as_view(),
|
||||||
|
name="delete_catrule",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"catrules/<int:pk>/edit",
|
||||||
|
CategorisationRuleUpdateView.as_view(),
|
||||||
|
name="edit_catrule",
|
||||||
|
),
|
||||||
|
path("catrules/apply", apply_categorisation_rules, name="apply_catrules"),
|
||||||
|
path("catrules/", categorisation_rules, name="categorisation_rules"),
|
||||||
# Errors
|
# Errors
|
||||||
path("500/", internal_server_error, name="internal_server_error"),
|
path("500/", internal_server_error, name="internal_server_error"),
|
||||||
path("404/", page_not_found, name="page_not_found"),
|
path("404/", page_not_found, name="page_not_found"),
|
||||||
@ -440,23 +459,6 @@ urlpatterns = [
|
|||||||
name="delete_rimport",
|
name="delete_rimport",
|
||||||
),
|
),
|
||||||
path("rimports/<int:pk>/run", run_rimport, name="run_rimport"),
|
path("rimports/<int:pk>/run", run_rimport, name="run_rimport"),
|
||||||
path("catrules/", categorisation_rules, name="categorisation_rules"),
|
|
||||||
path(
|
|
||||||
"catrules/add",
|
|
||||||
CategorisationRuleCreateView.as_view(),
|
|
||||||
name="add_catrule",
|
|
||||||
),
|
|
||||||
path(
|
|
||||||
"catrules/<int:pk>/edit",
|
|
||||||
CategorisationRuleUpdateView.as_view(),
|
|
||||||
name="edit_catrule",
|
|
||||||
),
|
|
||||||
path(
|
|
||||||
"catrules/<int:pk>/delete",
|
|
||||||
CategorisationRuleDeleteView.as_view(),
|
|
||||||
name="delete_catrule",
|
|
||||||
),
|
|
||||||
path("catrules/apply", apply_categorisation_rules, name="apply_catrules"),
|
|
||||||
path("duplicates/", duplicates, name="duplicates"),
|
path("duplicates/", duplicates, name="duplicates"),
|
||||||
path(
|
path(
|
||||||
"duplicates/<int:pk>",
|
"duplicates/<int:pk>",
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
from .oldviews import *
|
from .oldviews import *
|
||||||
|
from .categorisation_rules_view import *
|
||||||
from .errors import *
|
from .errors import *
|
||||||
from .general_pages_views import *
|
from .general_pages_views import *
|
||||||
from .moderation_views import *
|
from .moderation_views import *
|
||||||
|
192
src/agenda_culturel/views/categorisation_rules_view.py
Normal file
192
src/agenda_culturel/views/categorisation_rules_view.py
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
from django.contrib import messages
|
||||||
|
from django.contrib.auth.decorators import login_required, permission_required
|
||||||
|
from django.contrib.auth.mixins import PermissionRequiredMixin, LoginRequiredMixin
|
||||||
|
from django.contrib.messages.views import SuccessMessageMixin
|
||||||
|
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
|
||||||
|
from django.db.models import Q
|
||||||
|
from django.http import HttpResponseRedirect
|
||||||
|
from django.shortcuts import render
|
||||||
|
from django.urls import reverse_lazy
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from django.views.generic import UpdateView, CreateView, DeleteView
|
||||||
|
|
||||||
|
from ..forms import CategorisationRuleImportForm, CategorisationForm
|
||||||
|
from ..models import Event, CategorisationRule, Category
|
||||||
|
|
||||||
|
|
||||||
|
@login_required(login_url="/accounts/login/")
|
||||||
|
@permission_required("agenda_culturel.view_categorisationrule")
|
||||||
|
def categorisation_rules(request):
|
||||||
|
paginator = Paginator(
|
||||||
|
CategorisationRule.objects.all()
|
||||||
|
.order_by("pk")
|
||||||
|
.select_related("category")
|
||||||
|
.select_related("place"),
|
||||||
|
100,
|
||||||
|
)
|
||||||
|
page = request.GET.get("page")
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = paginator.page(page)
|
||||||
|
except PageNotAnInteger:
|
||||||
|
response = paginator.page(1)
|
||||||
|
except EmptyPage:
|
||||||
|
response = paginator.page(paginator.num_pages)
|
||||||
|
|
||||||
|
return render(
|
||||||
|
request,
|
||||||
|
"agenda_culturel/categorisation_rules.html",
|
||||||
|
{"paginator_filter": response},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class CategorisationRuleCreateView(
|
||||||
|
LoginRequiredMixin, PermissionRequiredMixin, CreateView
|
||||||
|
):
|
||||||
|
model = CategorisationRule
|
||||||
|
permission_required = "agenda_culturel.add_categorisationrule"
|
||||||
|
success_url = reverse_lazy("categorisation_rules")
|
||||||
|
form_class = CategorisationRuleImportForm
|
||||||
|
|
||||||
|
|
||||||
|
class CategorisationRuleUpdateView(
|
||||||
|
SuccessMessageMixin,
|
||||||
|
PermissionRequiredMixin,
|
||||||
|
LoginRequiredMixin,
|
||||||
|
UpdateView,
|
||||||
|
):
|
||||||
|
model = CategorisationRule
|
||||||
|
permission_required = "agenda_culturel.change_categorisationrule"
|
||||||
|
form_class = CategorisationRuleImportForm
|
||||||
|
success_url = reverse_lazy("categorisation_rules")
|
||||||
|
success_message = _("The categorisation rule has been successfully modified.")
|
||||||
|
|
||||||
|
|
||||||
|
class CategorisationRuleDeleteView(
|
||||||
|
SuccessMessageMixin,
|
||||||
|
PermissionRequiredMixin,
|
||||||
|
LoginRequiredMixin,
|
||||||
|
DeleteView,
|
||||||
|
):
|
||||||
|
model = CategorisationRule
|
||||||
|
permission_required = "agenda_culturel.delete_categorisationrule"
|
||||||
|
success_url = reverse_lazy("categorisation_rules")
|
||||||
|
success_message = _("The categorisation rule has been successfully deleted.")
|
||||||
|
|
||||||
|
|
||||||
|
@login_required(login_url="/accounts/login/")
|
||||||
|
@permission_required("agenda_culturel.apply_categorisationrules")
|
||||||
|
def apply_categorisation_rules(request):
|
||||||
|
if request.method == "POST":
|
||||||
|
form = CategorisationForm(request.POST)
|
||||||
|
if form.is_valid():
|
||||||
|
nb = 0
|
||||||
|
for epk, c in form.get_validated():
|
||||||
|
e = Event.objects.get(pk=epk)
|
||||||
|
cat = Category.objects.filter(name=c).first()
|
||||||
|
e.category = cat
|
||||||
|
e.save()
|
||||||
|
nb += 1
|
||||||
|
|
||||||
|
if nb != 0:
|
||||||
|
if nb == 1:
|
||||||
|
messages.success(
|
||||||
|
request,
|
||||||
|
_(
|
||||||
|
"The rules were successfully applied and 1 event was categorised."
|
||||||
|
),
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
messages.success(
|
||||||
|
request,
|
||||||
|
_(
|
||||||
|
"The rules were successfully applied and {} events were categorised."
|
||||||
|
).format(nb),
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
messages.info(
|
||||||
|
request,
|
||||||
|
_(
|
||||||
|
"The rules were successfully applied and no events were categorised."
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
return HttpResponseRedirect(reverse_lazy("categorisation_rules"))
|
||||||
|
else:
|
||||||
|
return render(
|
||||||
|
request,
|
||||||
|
"agenda_culturel/categorise_events_form.html",
|
||||||
|
context={"form": form},
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# first we check if events are not correctly categorised
|
||||||
|
to_categorise = []
|
||||||
|
events = (
|
||||||
|
Event.objects.filter(start_day__gte=datetime.now())
|
||||||
|
.exclude(category=Category.get_default_category_id())
|
||||||
|
.exclude(category=None)
|
||||||
|
.select_related("exact_location")
|
||||||
|
.select_related("category")
|
||||||
|
)
|
||||||
|
for e in events:
|
||||||
|
c = CategorisationRule.get_category_from_rules(e)
|
||||||
|
if c and c != e.category:
|
||||||
|
to_categorise.append((e, c))
|
||||||
|
|
||||||
|
# then we apply rules on events without category
|
||||||
|
nb = 0
|
||||||
|
to_save = []
|
||||||
|
events = (
|
||||||
|
Event.objects.filter(start_day__gte=datetime.now())
|
||||||
|
.filter(Q(category=Category.get_default_category_id()) | Q(category=None))
|
||||||
|
.select_related("exact_location")
|
||||||
|
.select_related("category")
|
||||||
|
)
|
||||||
|
for e in events:
|
||||||
|
success = CategorisationRule.apply_rules(e)
|
||||||
|
if success:
|
||||||
|
nb += 1
|
||||||
|
to_save.append(e)
|
||||||
|
|
||||||
|
if nb != 0:
|
||||||
|
Event.objects.bulk_update(to_save, fields=["category"])
|
||||||
|
|
||||||
|
# set messages
|
||||||
|
if nb != 0:
|
||||||
|
if nb == 1:
|
||||||
|
messages.success(
|
||||||
|
request,
|
||||||
|
_(
|
||||||
|
"The rules were successfully applied and 1 event with default category was categorised."
|
||||||
|
),
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
messages.success(
|
||||||
|
request,
|
||||||
|
_(
|
||||||
|
"The rules were successfully applied and {} events with default category were categorised."
|
||||||
|
).format(nb),
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
messages.info(
|
||||||
|
request,
|
||||||
|
_(
|
||||||
|
"The rules were successfully applied and no events were categorised."
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
if len(to_categorise) != 0:
|
||||||
|
form = CategorisationForm(events=to_categorise)
|
||||||
|
return render(
|
||||||
|
request,
|
||||||
|
"agenda_culturel/categorise_events_form.html",
|
||||||
|
context={
|
||||||
|
"form": form,
|
||||||
|
"events": dict((e.pk, e) for e, c in to_categorise),
|
||||||
|
"categories": dict((e.pk, c) for e, c in to_categorise),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return HttpResponseRedirect(reverse_lazy("categorisation_rules"))
|
@ -41,6 +41,7 @@ from django.views.generic.edit import (
|
|||||||
)
|
)
|
||||||
from honeypot.decorators import check_honeypot
|
from honeypot.decorators import check_honeypot
|
||||||
|
|
||||||
|
from .utils import get_event_qs
|
||||||
from ..calendar import CalendarDay, CalendarList, CalendarMonth, CalendarWeek
|
from ..calendar import CalendarDay, CalendarList, CalendarMonth, CalendarWeek
|
||||||
from ..celery import app as celery_app
|
from ..celery import app as celery_app
|
||||||
from ..celery import (
|
from ..celery import (
|
||||||
@ -64,8 +65,6 @@ from ..filters import (
|
|||||||
)
|
)
|
||||||
from ..forms import (
|
from ..forms import (
|
||||||
BatchImportationForm,
|
BatchImportationForm,
|
||||||
CategorisationForm,
|
|
||||||
CategorisationRuleImportForm,
|
|
||||||
EventForm,
|
EventForm,
|
||||||
EventFormWithContact,
|
EventFormWithContact,
|
||||||
FixDuplicates,
|
FixDuplicates,
|
||||||
@ -82,7 +81,6 @@ from ..forms import (
|
|||||||
from ..import_tasks.extractor import Extractor
|
from ..import_tasks.extractor import Extractor
|
||||||
from ..models import (
|
from ..models import (
|
||||||
BatchImportation,
|
BatchImportation,
|
||||||
CategorisationRule,
|
|
||||||
Category,
|
Category,
|
||||||
DuplicatedEvents,
|
DuplicatedEvents,
|
||||||
Event,
|
Event,
|
||||||
@ -94,7 +92,6 @@ from ..models import (
|
|||||||
remove_accents,
|
remove_accents,
|
||||||
UserProfile,
|
UserProfile,
|
||||||
)
|
)
|
||||||
from .utils import get_event_qs
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -1954,187 +1951,6 @@ def set_duplicate(request, year, month, day, pk):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
#########################
|
|
||||||
## categorisation rules
|
|
||||||
#########################
|
|
||||||
|
|
||||||
|
|
||||||
@login_required(login_url="/accounts/login/")
|
|
||||||
@permission_required("agenda_culturel.view_categorisationrule")
|
|
||||||
def categorisation_rules(request):
|
|
||||||
paginator = Paginator(
|
|
||||||
CategorisationRule.objects.all()
|
|
||||||
.order_by("pk")
|
|
||||||
.select_related("category")
|
|
||||||
.select_related("place"),
|
|
||||||
100,
|
|
||||||
)
|
|
||||||
page = request.GET.get("page")
|
|
||||||
|
|
||||||
try:
|
|
||||||
response = paginator.page(page)
|
|
||||||
except PageNotAnInteger:
|
|
||||||
response = paginator.page(1)
|
|
||||||
except EmptyPage:
|
|
||||||
response = paginator.page(paginator.num_pages)
|
|
||||||
|
|
||||||
return render(
|
|
||||||
request,
|
|
||||||
"agenda_culturel/categorisation_rules.html",
|
|
||||||
{"paginator_filter": response},
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class CategorisationRuleCreateView(
|
|
||||||
LoginRequiredMixin, PermissionRequiredMixin, CreateView
|
|
||||||
):
|
|
||||||
model = CategorisationRule
|
|
||||||
permission_required = "agenda_culturel.add_categorisationrule"
|
|
||||||
success_url = reverse_lazy("categorisation_rules")
|
|
||||||
form_class = CategorisationRuleImportForm
|
|
||||||
|
|
||||||
|
|
||||||
class CategorisationRuleUpdateView(
|
|
||||||
SuccessMessageMixin,
|
|
||||||
PermissionRequiredMixin,
|
|
||||||
LoginRequiredMixin,
|
|
||||||
UpdateView,
|
|
||||||
):
|
|
||||||
model = CategorisationRule
|
|
||||||
permission_required = "agenda_culturel.change_categorisationrule"
|
|
||||||
form_class = CategorisationRuleImportForm
|
|
||||||
success_url = reverse_lazy("categorisation_rules")
|
|
||||||
success_message = _("The categorisation rule has been successfully modified.")
|
|
||||||
|
|
||||||
|
|
||||||
class CategorisationRuleDeleteView(
|
|
||||||
SuccessMessageMixin,
|
|
||||||
PermissionRequiredMixin,
|
|
||||||
LoginRequiredMixin,
|
|
||||||
DeleteView,
|
|
||||||
):
|
|
||||||
model = CategorisationRule
|
|
||||||
permission_required = "agenda_culturel.delete_categorisationrule"
|
|
||||||
success_url = reverse_lazy("categorisation_rules")
|
|
||||||
success_message = _("The categorisation rule has been successfully deleted.")
|
|
||||||
|
|
||||||
|
|
||||||
@login_required(login_url="/accounts/login/")
|
|
||||||
@permission_required("agenda_culturel.apply_categorisationrules")
|
|
||||||
def apply_categorisation_rules(request):
|
|
||||||
if request.method == "POST":
|
|
||||||
form = CategorisationForm(request.POST)
|
|
||||||
if form.is_valid():
|
|
||||||
nb = 0
|
|
||||||
for epk, c in form.get_validated():
|
|
||||||
e = Event.objects.get(pk=epk)
|
|
||||||
cat = Category.objects.filter(name=c).first()
|
|
||||||
e.category = cat
|
|
||||||
e.save()
|
|
||||||
nb += 1
|
|
||||||
|
|
||||||
if nb != 0:
|
|
||||||
if nb == 1:
|
|
||||||
messages.success(
|
|
||||||
request,
|
|
||||||
_(
|
|
||||||
"The rules were successfully applied and 1 event was categorised."
|
|
||||||
),
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
messages.success(
|
|
||||||
request,
|
|
||||||
_(
|
|
||||||
"The rules were successfully applied and {} events were categorised."
|
|
||||||
).format(nb),
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
messages.info(
|
|
||||||
request,
|
|
||||||
_(
|
|
||||||
"The rules were successfully applied and no events were categorised."
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
return HttpResponseRedirect(reverse_lazy("categorisation_rules"))
|
|
||||||
else:
|
|
||||||
return render(
|
|
||||||
request,
|
|
||||||
"agenda_culturel/categorise_events_form.html",
|
|
||||||
context={"form": form},
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
# first we check if events are not correctly categorised
|
|
||||||
to_categorise = []
|
|
||||||
events = (
|
|
||||||
Event.objects.filter(start_day__gte=datetime.now())
|
|
||||||
.exclude(category=Category.get_default_category_id())
|
|
||||||
.exclude(category=None)
|
|
||||||
.select_related("exact_location")
|
|
||||||
.select_related("category")
|
|
||||||
)
|
|
||||||
for e in events:
|
|
||||||
c = CategorisationRule.get_category_from_rules(e)
|
|
||||||
if c and c != e.category:
|
|
||||||
to_categorise.append((e, c))
|
|
||||||
|
|
||||||
# then we apply rules on events without category
|
|
||||||
nb = 0
|
|
||||||
to_save = []
|
|
||||||
events = (
|
|
||||||
Event.objects.filter(start_day__gte=datetime.now())
|
|
||||||
.filter(Q(category=Category.get_default_category_id()) | Q(category=None))
|
|
||||||
.select_related("exact_location")
|
|
||||||
.select_related("category")
|
|
||||||
)
|
|
||||||
for e in events:
|
|
||||||
success = CategorisationRule.apply_rules(e)
|
|
||||||
if success:
|
|
||||||
nb += 1
|
|
||||||
to_save.append(e)
|
|
||||||
|
|
||||||
if nb != 0:
|
|
||||||
Event.objects.bulk_update(to_save, fields=["category"])
|
|
||||||
|
|
||||||
# set messages
|
|
||||||
if nb != 0:
|
|
||||||
if nb == 1:
|
|
||||||
messages.success(
|
|
||||||
request,
|
|
||||||
_(
|
|
||||||
"The rules were successfully applied and 1 event with default category was categorised."
|
|
||||||
),
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
messages.success(
|
|
||||||
request,
|
|
||||||
_(
|
|
||||||
"The rules were successfully applied and {} events with default category were categorised."
|
|
||||||
).format(nb),
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
messages.info(
|
|
||||||
request,
|
|
||||||
_(
|
|
||||||
"The rules were successfully applied and no events were categorised."
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
if len(to_categorise) != 0:
|
|
||||||
form = CategorisationForm(events=to_categorise)
|
|
||||||
return render(
|
|
||||||
request,
|
|
||||||
"agenda_culturel/categorise_events_form.html",
|
|
||||||
context={
|
|
||||||
"form": form,
|
|
||||||
"events": dict((e.pk, e) for e, c in to_categorise),
|
|
||||||
"categories": dict((e.pk, c) for e, c in to_categorise),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
return HttpResponseRedirect(reverse_lazy("categorisation_rules"))
|
|
||||||
|
|
||||||
|
|
||||||
def statistics(request, pk=None):
|
def statistics(request, pk=None):
|
||||||
if pk is not None:
|
if pk is not None:
|
||||||
rimport = RecurrentImport.objects.filter(pk=pk)
|
rimport = RecurrentImport.objects.filter(pk=pk)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user