forked from DGNum/gestioCOF
Merge branch 'kerl/event_subscriptions' into 'master'
[Événements] Export des inscrits en csv See merge request klub-dev-ens/gestioCOF!374
This commit is contained in:
commit
7892f42e3e
7 changed files with 128 additions and 2 deletions
|
@ -123,6 +123,12 @@ urlpatterns = [
|
|||
path("config", gestioncof_views.ConfigUpdate.as_view(), name="config.edit"),
|
||||
]
|
||||
|
||||
if "events" in settings.INSTALLED_APPS:
|
||||
# The new event application is still in development
|
||||
# → for now it is namespaced below events_v2
|
||||
# → when the old events system is out, move this above in the others apps
|
||||
urlpatterns += [path("event_v2/", include("events.urls"))]
|
||||
|
||||
if "debug_toolbar" in settings.INSTALLED_APPS:
|
||||
import debug_toolbar
|
||||
|
||||
|
|
22
events/migrations/0002_event_subscribers.py
Normal file
22
events/migrations/0002_event_subscribers.py
Normal file
|
@ -0,0 +1,22 @@
|
|||
# Generated by Django 2.2.6 on 2019-10-05 13:03
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
("events", "0001_event"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="event",
|
||||
name="subscribers",
|
||||
field=models.ManyToManyField(
|
||||
to=settings.AUTH_USER_MODEL, verbose_name="inscrit⋅e⋅s"
|
||||
),
|
||||
)
|
||||
]
|
|
@ -1,6 +1,9 @@
|
|||
from django.contrib.auth import get_user_model
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
class Event(models.Model):
|
||||
title = models.CharField(_("titre"), max_length=200)
|
||||
|
@ -13,6 +16,7 @@ class Event(models.Model):
|
|||
)
|
||||
registration_open = models.BooleanField(_("inscriptions ouvertes"), default=True)
|
||||
old = models.BooleanField(_("archiver (événement fini)"), default=False)
|
||||
subscribers = models.ManyToManyField(User, verbose_name=_("inscrit⋅e⋅s"))
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("événement")
|
||||
|
@ -22,8 +26,6 @@ class Event(models.Model):
|
|||
return self.title
|
||||
|
||||
|
||||
# TODO: gérer les inscriptions
|
||||
|
||||
# TODO: gérer les options (EventOption & EventOptionChoice de gestioncof)
|
||||
# par exemple: "option végé au Mega (oui / non)"
|
||||
|
||||
|
|
0
events/tests/__init__.py
Normal file
0
events/tests/__init__.py
Normal file
59
events/tests/test_views.py
Normal file
59
events/tests/test_views.py
Normal file
|
@ -0,0 +1,59 @@
|
|||
from unittest import mock
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.test import Client, TestCase
|
||||
from django.urls import reverse
|
||||
|
||||
from events.models import Event
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
def make_user(name):
|
||||
return User.objects.create_user(username=name, password=name)
|
||||
|
||||
|
||||
def make_staff_user(name):
|
||||
view_event_perm = Permission.objects.get_by_natural_key(
|
||||
codename="view_event", app_label="events", model="event"
|
||||
)
|
||||
user = make_user(name)
|
||||
user.user_permissions.add(view_event_perm)
|
||||
return user
|
||||
|
||||
|
||||
class CSVExportTest(TestCase):
|
||||
def setUp(self):
|
||||
# Signals handlers on login/logout send messages.
|
||||
# Due to the way the Django' test Client performs login, this raise an
|
||||
# error. As workaround, we mock the Django' messages module.
|
||||
patcher_messages = mock.patch("gestioncof.signals.messages")
|
||||
patcher_messages.start()
|
||||
self.addCleanup(patcher_messages.stop)
|
||||
|
||||
self.staff = make_staff_user("staff")
|
||||
self.u1 = make_user("toto")
|
||||
self.u2 = make_user("titi")
|
||||
self.event = Event.objects.create(title="test_event", location="somewhere")
|
||||
self.event.subscribers.set([self.u1, self.u2])
|
||||
self.url = reverse("events:csv-participants", args=[self.event.id])
|
||||
|
||||
def test_get(self):
|
||||
client = Client()
|
||||
client.force_login(self.staff)
|
||||
r = client.get(self.url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
|
||||
def test_anonymous(self):
|
||||
client = Client()
|
||||
r = client.get(self.url)
|
||||
self.assertRedirects(
|
||||
r, "/login?next={}".format(self.url), fetch_redirect_response=False
|
||||
)
|
||||
|
||||
def test_unauthorised(self):
|
||||
client = Client()
|
||||
client.force_login(self.u1)
|
||||
r = client.get(self.url)
|
||||
self.assertEqual(r.status_code, 403)
|
12
events/urls.py
Normal file
12
events/urls.py
Normal file
|
@ -0,0 +1,12 @@
|
|||
from django.urls import path
|
||||
|
||||
from events import views
|
||||
|
||||
app_name = "events"
|
||||
urlpatterns = [
|
||||
path(
|
||||
"csv/participants/<int:event_id>",
|
||||
views.participants_csv,
|
||||
name="csv-participants",
|
||||
)
|
||||
]
|
|
@ -0,0 +1,25 @@
|
|||
import csv
|
||||
|
||||
from django.contrib.auth.decorators import login_required, permission_required
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.utils.text import slugify
|
||||
|
||||
from events.models import Event
|
||||
|
||||
|
||||
@login_required
|
||||
@permission_required("events.view_event", raise_exception=True)
|
||||
def participants_csv(request, event_id):
|
||||
event = get_object_or_404(Event, id=event_id)
|
||||
|
||||
filename = "{}-participants.csv".format(slugify(event.title))
|
||||
response = HttpResponse(content_type="text/csv")
|
||||
response["Content-Disposition"] = 'attachment; filename="{}"'.format(filename)
|
||||
|
||||
writer = csv.writer(response)
|
||||
writer.writerow(["username", "email", "prénom", "nom de famille"])
|
||||
for user in event.subscribers.all():
|
||||
writer.writerow([user.username, user.email, user.first_name, user.last_name])
|
||||
|
||||
return response
|
Loading…
Reference in a new issue