diff --git a/oser_backend/settings/common.py b/oser_backend/settings/common.py index d5b680545e27f2eaba92f2c95db80e1c1a881ce5..84ccf8246385333d1cfbb3d32340090720319435 100644 --- a/oser_backend/settings/common.py +++ b/oser_backend/settings/common.py @@ -264,7 +264,7 @@ SENDGRID_ECHO_TO_STDOUT = True MAILS_ENABLED = True MAILS_NOTIFICATIONS_ADDRESS = 'notifications@oser-cs.fr' -MAILS_RAISE_EXCEPTIONS = True +MAILS_RAISE_EXCEPTIONS = False # Visits app config VISITS_TEAM_EMAIL = os.environ.get('VISITS_TEAM_EMAIL', diff --git a/profiles/admin.py b/profiles/admin.py index f7fc71a9d3b7986b4b743f0b447cbac778d6b89a..6aefa1a15a823939b603430a933abd9852706f31 100644 --- a/profiles/admin.py +++ b/profiles/admin.py @@ -50,4 +50,5 @@ class StudentAdmin(ProfileAdminMixin, admin.ModelAdmin,ExportCsvMixin): list_filter = (('school',MultiSelectFieldListFilter), 'year', 'registration__validated') class Meta: # noqa model = Student + ordering = ['updated_date'] actions = ["export_as_csv"] \ No newline at end of file diff --git a/profiles/migrations/0015_student_updated_date.py b/profiles/migrations/0015_student_updated_date.py new file mode 100644 index 0000000000000000000000000000000000000000..4e672b5fbb499a6886e6d4868f6ae9ccc47f8d35 --- /dev/null +++ b/profiles/migrations/0015_student_updated_date.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2 on 2021-01-15 17:06 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('profiles', '0014_auto_20201116_1118'), + ] + + operations = [ + migrations.AddField( + model_name='student', + name='updated_date', + field=models.DateTimeField(auto_now=True), + ), + ] diff --git a/profiles/models.py b/profiles/models.py index 20952a31436e83bbaeed223aad3fbd091638b319..4c9d912bbe6d1fb16a44290e0d73de85c898c5d1 100644 --- a/profiles/models.py +++ b/profiles/models.py @@ -38,6 +38,8 @@ class Student(ProfileMixin, models.Model): detail_view_name = 'api:student-detail' + updated_date = models.DateTimeField(auto_now=True) + user = models.OneToOneField( 'users.User', on_delete=models.CASCADE, diff --git a/register/admin.py b/register/admin.py index 175b18297bfcddffba5a0dc98e1c653682f54924..34e2c392f051eaa955aba89c63ec8ae97d9e0fea 100644 --- a/register/admin.py +++ b/register/admin.py @@ -4,7 +4,43 @@ from django.contrib import admin from .models import Registration from profiles.models import Student -# Register your models here. + +class SchoolFilter(admin.SimpleListFilter): + title = 'établissement' + parameter_name = 'profiles__school' + + def lookups(self, request, model_admin): + list_of_school = [] + query = Student.objects.values_list( + "school", flat=True).distinct() + for school in query: + list_of_school.append((school, school)) + return list_of_school + + def queryset(self, request, queryset): + if self.value(): + emails = Student.objects.filter( + school=self.value()).values_list("user__email", flat=True) + return queryset.filter(email__in=emails) + + +class SchoolFilter(admin.SimpleListFilter): + title = 'établissement' + parameter_name = 'profiles__school' + + def lookups(self, request, model_admin): + list_of_school = [] + query = Student.objects.values_list( + "school", flat=True).distinct() + for school in query: + list_of_school.append((school, school)) + return list_of_school + + def queryset(self, request, queryset): + if self.value(): + emails = Student.objects.filter( + school=self.value()).values_list("user__email", flat=True) + return queryset.filter(email__in=emails) class SchoolFilter(admin.SimpleListFilter): diff --git a/visits/admin.py b/visits/admin.py index 0bf0ad5f8fe8a23189cc4d71d1656421ab4ff454..f37a9af283aabb7feea90d105046d7c2f99aac5b 100644 --- a/visits/admin.py +++ b/visits/admin.py @@ -95,11 +95,28 @@ class VisitForm(forms.ModelForm): self.add_error('end_time', error) -class ParticipationInline(admin.StackedInline): +class ParticipationInline(admin.TabularInline): """Inline for Participation.""" - + # template = "visits/visit_tabular.md" + actions = ["export_as_csv"] model = Visit.participants.through extra = 0 + fields = ('name', 'school', 'user', 'submitted', 'present') + readonly_fields = ('name', 'school', 'user', 'submitted') + + def school(self, participation: Participation): + """Return a link to the participation's user's school.""" + school = Student.objects.get(user=participation.user).school + return school + school.short_description = "Établissement" + + def name(self, participation: Participation): + """Returns the participation's user's name""" + return participation.user.first_name + " " + participation.user.last_name + name.short_description = "Nom" + + class Media: + css = {"all": ("css/hide_admin_original.css",)} def accept_selected_participations(modeladmin, request, queryset): @@ -150,6 +167,12 @@ class ParticipationAdmin(admin.ModelAdmin): actions = ["export_as_csv"] + def school(self, participation: Participation): + """Return a link to the participation's user's school.""" + school = Student.objects.get(user=participation.user).school + return school + school.short_description = "Établissement" + def export_as_csv(self, request, queryset): meta = self.model._meta field_names = [field.name for field in meta.fields] @@ -179,6 +202,12 @@ class ParticipationAdmin(admin.ModelAdmin): export_as_csv.short_description = "Exporter sélection (en .csv)" +<< << << < HEAD +== == == = + +>>>>>> > f3728719809bca5d0418070e56327751d8f7a3aa + + @ admin.register(Visit.organizers.through) class VisitOrganizersAdmin(admin.ModelAdmin): """Admin panel for visit organizers.""" diff --git a/visits/templates/visits/visit_tabular.md b/visits/templates/visits/visit_tabular.md new file mode 100644 index 0000000000000000000000000000000000000000..f96903bb78ded1b7140e407cb9691f54716a9821 --- /dev/null +++ b/visits/templates/visits/visit_tabular.md @@ -0,0 +1,79 @@ +{% load i18n admin_urls static admin_modify %} +<div class="js-inline-admin-formset inline-group" id="{{ inline_admin_formset.formset.prefix }}-group" + data-inline-type="tabular" + data-inline-formset="{{ inline_admin_formset.inline_formset_data }}"> + <div class="tabular inline-related {% if forloop.last %}last-related{% endif %}"> +{{ inline_admin_formset.formset.management_form }} +<fieldset class="module {{ inline_admin_formset.classes }}"> + {% if inline_admin_formset.formset.max_num == 1 %} + <h2>{{ inline_admin_formset.opts.verbose_name|capfirst }}</h2> + {% else %} + <h2>{{ inline_admin_formset.opts.verbose_name_plural|capfirst }}</h2> + {% endif %} + {{ inline_admin_formset.formset.non_form_errors }} + <table> + <thead><tr> + <th class="original"></th> + {% for field in inline_admin_formset.fields %} + {% if not field.widget.is_hidden %} + <th class="column-{{ field.name }}{% if field.required %} required{% endif %}">{{ field.label|capfirst }} + {% if field.help_text %}<img src="{% static "admin/img/icon-unknown.svg" %}" class="help help-tooltip" width="10" height="10" alt="({{ field.help_text|striptags }})" title="{{ field.help_text|striptags }}">{% endif %} + </th> + {% endif %} + {% endfor %} + {% if inline_admin_formset.formset.can_delete and inline_admin_formset.has_delete_permission %}<th>{% translate "Delete?" %}</th>{% endif %} + </tr></thead> + + <tbody> + {% for inline_admin_form in inline_admin_formset %} + {% if inline_admin_form.form.non_field_errors %} + <tr class="row-form-errors"><td colspan="{{ inline_admin_form|cell_count }}">{{ inline_admin_form.form.non_field_errors }}</td></tr> + {% endif %} + <tr class="form-row {% if inline_admin_form.original or inline_admin_form.show_url %}has_original{% endif %}{% if forloop.last and inline_admin_formset.has_add_permission %} empty-form{% endif %}" + id="{{ inline_admin_formset.formset.prefix }}-{% if not forloop.last %}{{ forloop.counter0 }}{% else %}empty{% endif %}"> + <td class="original"> + {% if inline_admin_form.original or inline_admin_form.show_url %}<p> + {% if inline_admin_form.original %} + {{ inline_admin_form.original }} + {% if inline_admin_form.model_admin.show_change_link and inline_admin_form.model_admin.has_registered_model %}<a href="{% url inline_admin_form.model_admin.opts|admin_urlname:'change' inline_admin_form.original.pk|admin_urlquote %}" class="{% if inline_admin_formset.has_change_permission %}inlinechangelink{% else %}inlineviewlink{% endif %}">{% if inline_admin_formset.has_change_permission %}{% translate "Change" %}{% else %}{% translate "View" %}{% endif %}</a>{% endif %} + {% endif %} + {% if inline_admin_form.show_url %}<a href="{{ inline_admin_form.absolute_url }}">{% translate "View on site" %}</a>{% endif %} + </p>{% endif %} + {% if inline_admin_form.needs_explicit_pk_field %}{{ inline_admin_form.pk_field.field }}{% endif %} + {% if inline_admin_form.fk_field %}{{ inline_admin_form.fk_field.field }}{% endif %} + {% spaceless %} + {% for fieldset in inline_admin_form %} + {% for line in fieldset %} + {% for field in line %} + {% if not field.is_readonly and field.field.is_hidden %}{{ field.field }}{% endif %} + {% endfor %} + {% endfor %} + {% endfor %} + {% endspaceless %} + </td> + {% for fieldset in inline_admin_form %} + {% for line in fieldset %} + {% for field in line %} + {% if field.is_readonly or not field.field.is_hidden %} + <td{% if field.field.name %} class="field-{{ field.field.name }}"{% endif %}> + {% if field.is_readonly %} + <p>{{ field.contents }}</p> + {% else %} + {{ field.field.errors.as_ul }} + {{ field.field }} + {% endif %} + </td> + {% endif %} + {% endfor %} + {% endfor %} + {% endfor %} + {% if inline_admin_formset.formset.can_delete and inline_admin_formset.has_delete_permission %} + <td class="delete">{% if inline_admin_form.original %}{{ inline_admin_form.deletion_field.field }}{% endif %}</td> + {% endif %} + </tr> + {% endfor %} + </tbody> + </table> +</fieldset> + </div> +</div> \ No newline at end of file