]> git.parisson.com Git - teleforma.git/commitdiff
Conferences can now have multiple professors pb-docker-dev
authorYoan Le Clanche <yoanl@pilotsystems.net>
Mon, 24 Aug 2026 08:37:27 +0000 (10:37 +0200)
committerYoan Le Clanche <yoanl@pilotsystems.net>
Mon, 24 Aug 2026 08:37:27 +0000 (10:37 +0200)
12 files changed:
teleforma/admin.py
teleforma/migrations/0027_conference_professor_m2m.py [new file with mode: 0644]
teleforma/models/core.py
teleforma/templates/teleforma/course.html
teleforma/templates/teleforma/course_conference.html
teleforma/templates/teleforma/course_conference_audio.html
teleforma/templates/teleforma/course_media.html
teleforma/templates/teleforma/course_media_transcoded.html
teleforma/templates/teleforma/course_webclass.html
teleforma/templates/teleforma/inc/conference_list.html
teleforma/templates/teleforma/inc/media_list.html
teleforma/views/core.py

index 753fb6f0b18a90c7305b8b9042d828a223ad38f9..189c609e874b622d779fe90c323c57f476bfe6f6 100644 (file)
@@ -169,6 +169,7 @@ class MediaAdmin(admin.ModelAdmin):
 class ConferenceAdmin(admin.ModelAdmin):
     exclude = ['readers', 'keywords']
     search_fields = ['public_id', 'id', 'title']
+    filter_horizontal = ['professor',]
     autocomplete_fields = ['docs_description',
                            'suggested_seminars', 'suggested_conferences']
     actions = ['export_conference']
diff --git a/teleforma/migrations/0027_conference_professor_m2m.py b/teleforma/migrations/0027_conference_professor_m2m.py
new file mode 100644 (file)
index 0000000..6a16d9e
--- /dev/null
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+from django.db import migrations, models
+
+
+def copy_professor(apps, schema_editor):
+    """Move the single FK professor into the new M2M relation."""
+    Conference = apps.get_model('teleforma', 'Conference')
+    for conf in Conference.objects.exclude(professor_single__isnull=True):
+        conf.professor.add(conf.professor_single_id)
+
+
+def reverse_professor(apps, schema_editor):
+    """Keep the first M2M professor as the single FK professor."""
+    Conference = apps.get_model('teleforma', 'Conference')
+    for conf in Conference.objects.all():
+        first = conf.professor.first()
+        if first:
+            conf.professor_single = first
+            conf.save(update_fields=['professor_single'])
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('teleforma', '0026_conference_secondary_subject'),
+    ]
+
+    operations = [
+        migrations.RenameField(
+            model_name='conference',
+            old_name='professor',
+            new_name='professor_single',
+        ),
+        migrations.AddField(
+            model_name='conference',
+            name='professor',
+            field=models.ManyToManyField(blank=True, related_name='conference', to='teleforma.Professor', verbose_name='professor'),
+        ),
+        migrations.RunPython(copy_professor, reverse_professor),
+        migrations.RemoveField(
+            model_name='conference',
+            name='professor_single',
+        ),
+    ]
index fd243a576873e7ab23c74ebb083fa809cb9e9a4d..8d573b8840103e98a0dd150ac21d30e8fd4bf40b 100755 (executable)
@@ -964,8 +964,8 @@ class Conference(Displayable, WebclassMixin, ProductCodeMixin, SuggestionsMixin)
     course          = models.ForeignKey('Course', related_name='conference', verbose_name=_('course'), on_delete=models.CASCADE)
     course_type     = models.ForeignKey('CourseType', related_name='conference', verbose_name=_('course type'),
                                  null=True, blank=True, on_delete=models.SET_NULL)
-    professor       = models.ForeignKey('Professor', related_name='conference', verbose_name=_('professor'),
-                                 blank=True, null=True, on_delete=models.SET_NULL)
+    professor       = models.ManyToManyField('Professor', related_name='conference', verbose_name=_('professor'),
+                                 blank=True)
     session         = models.CharField(_('session'), choices=session_choices,
                                       max_length=16, default="1")
     
@@ -1076,16 +1076,12 @@ class Conference(Displayable, WebclassMixin, ProductCodeMixin, SuggestionsMixin)
             }
 
     def __str__(self):
-        if self.professor:
-            list = [self.title, self.course.title,
-                           self.session,
-                           self.professor.user.first_name,
-                           self.professor.user.last_name,
-                           str(self.date_begin)]
-        else:
-            list = [self.title, self.course.title,
-                           self.session,
-                           str(self.date_begin)]
+        list = [self.title, self.course.title, self.session]
+        if self.pk:
+            for professor in self.professor.all():
+                list.append(professor.user.first_name)
+                list.append(professor.user.last_name)
+        list.append(str(self.date_begin))
         return ' - '.join(list)
 
     def save(self, **kwargs):
@@ -1098,16 +1094,18 @@ class Conference(Displayable, WebclassMixin, ProductCodeMixin, SuggestionsMixin)
                 {'id':'organization','value': self.course.department.organization, 'class':'', 'label': 'Organization'},
                 {'id': 'department', 'value': self.course.department , 'class':'', 'label': 'Department'},
                 {'id': 'period', 'value': self.period, 'class':'', 'label': 'Period'},
-                {'id': 'professor', 'value': self.professor, 'class':'' , 'label': 'Professor'},
+                {'id': 'professor', 'value': ', '.join(str(p) for p in self.professor.all()), 'class':'' , 'label': 'Professor'},
                 {'id': 'session', 'value': self.session, 'class':'' , 'label': 'Session'},
                 {'id': 'comment', 'value': self.comment, 'class':'' , 'label': 'Comment'},
                 ]
         return dict
 
     def to_json_dict(self):
+        professors = self.professor.all()
         data = {'id': self.public_id,
                 'course_code': self.course.code,
-                'professor_id': self.professor.user.username,
+                'professor_id': professors[0].user.username if professors else '',
+                'professor_ids': [p.user.username for p in professors],
                 'period': self.period.name,
                 'department': self.department.name,
                 'session': self.session,
index 96c3862caf2e08a0bf8c49d6a9bd87244944f29c..aa8418e592c7c356a8b7691abab337a6b2fcb975 100644 (file)
@@ -54,7 +54,7 @@
 {% for conference in course.conference.all %}
 <tr {% if not forloop.counter0|divisibleby:"2" %}class="odd"{% endif %}>
 <td>{{ conference.session }}</td>
-<td>{{ conference.professor.user.first_name }} {{ conference.professor.user.last_name }}</td>
+<td>{% for professor in conference.professor.all %}{{ professor.user.first_name }} {{ professor.user.last_name }}{% if not forloop.last %}, {% endif %}{% endfor %}</td>
 <td>{{ conference.date_begin }}</td>
 </tr>
 
index 46b69e32e61bbe348d95fdfff0d6fbaa7b2473d8..2a34eef6ace94f5b77819110bce94916c7c91f14 100644 (file)
 <div class="course_content" id="media_infos">
 <dl class="listing">
 
-{% if conference.professor %}
+{% if conference.professor.all %}
 <dt>{% trans "Course" %}</dt><dd><a href="{% url 'teleforma-course-detail' course.id %}">{{ conference.course.title }} - {{ conference.course_type }}</a></dd>
 <dt>{% trans "Session" %}</dt><dd>{{ conference.session }}</dd>
-<dt>{% trans "Professor" %}</dt>
-    <dd><a href="{% url 'teleforma-profile-detail' conference.professor.user.username %}" target="_blank">{{ conference.professor }}</a></dd>
+<dt>{% if conference.professor.count > 1 %}{% trans "Professors" %}{% else %}{% trans "Professor" %}{% endif %}</dt>
+    <dd>{% for professor in conference.professor.all %}<a href="{% url 'teleforma-profile-detail' professor.user.username %}" target="_blank">{{ professor }}</a>{% if not forloop.last %}, {% endif %}{% endfor %}</dd>
 {% endif %}
 {% if conference.comment %}<dt>{% trans "Comment" %}</dt><dd>{{ conference.comment }}</dd>{% endif %}
 <dt>{% trans "Begin date" %}</dt><dd>{{ conference.date_begin }}</dd>
index 26e0599c78e5d4bab4094c772d6fefb6638cbed0..c0ba0d240cbff8be5cd785f2a480ae41007831ba 100644 (file)
@@ -35,7 +35,7 @@
         <a href="{% url 'teleforma-conference-detail' conference.id %}" class="component_icon button icon_clap">&nbsp;{% trans "Video" %}</a>
     </div>
 
-{{ course.title }}{% if course.description %} - {{ course.description }}{% endif %} - {{ conference.session }} - {{ conference.professor }}
+{{ course.title }}{% if course.description %} - {{ course.description }}{% endif %} - {{ conference.session }} - {% for professor in conference.professor.all %}{{ professor }}{% if not forloop.last %}, {% endif %}{% endfor %}
 </div>
 
 <div class="media">
@@ -63,7 +63,7 @@
 <div class="course_content" id="media_infos">
 <dl class="listing">
 <dt>{% trans "Title" %}</dt><dd>{{ conference.course.title }}</dd>
-<dt>{% trans "Professor" %}</dt><dd><a href="{% url 'teleforma-profile-detail' conference.professor.user.username %}" target="_blank">{{ conference.professor }}</a></dd>
+<dt>{% if conference.professor.count > 1 %}{% trans "Professors" %}{% else %}{% trans "Professor" %}{% endif %}</dt><dd>{% for professor in conference.professor.all %}<a href="{% url 'teleforma-profile-detail' professor.user.username %}" target="_blank">{{ professor }}</a>{% if not forloop.last %}, {% endif %}{% endfor %}</dd>
 <dt>{% trans "Session" %}</dt><dd>{{ conference.session }}</dd>
 <dt>{% trans "Room" %}</dt><dd>{{ conference.room }}</dd>
 <dt>{% trans "Begin" %}</dt><dd>{{ conference.date_begin }}</dd>
index de28f8cf7e147ff35f5a199c067092e867285f96..da3b957dbc4e0825d8ab8e485770201b2e76db0f 100644 (file)
 {% if media.conference %}
 <dt>{% trans "Course" %}</dt><dd><a href="{% url 'teleforma-course-detail' course.id %}">{{ media.course.title }} - {{ media.course_type }}</a></dd>
 <dt>{% trans "Session" %}</dt><dd>{{ media.conference.session }}</dd>
-{% if media.conference.professor %}
-<dt>{% trans "Professor" %}</dt>
-    <dd><a href="{% url 'teleforma-profile-detail' media.conference.professor.user.username %}" target="_blank">{{ media.conference.professor }}</a></dd>
+{% if media.conference.professor.all %}
+<dt>{% if media.conference.professor.count > 1 %}{% trans "Professors" %}{% else %}{% trans "Professor" %}{% endif %}</dt>
+    <dd>{% for professor in media.conference.professor.all %}<a href="{% url 'teleforma-profile-detail' professor.user.username %}" target="_blank">{{ professor }}</a>{% if not forloop.last %}, {% endif %}{% endfor %}</dd>
 {% endif %}
 {% if media.conference.comment %}<dt>{% trans "Comment" %}</dt><dd>{{ media.conference.comment }}</dd>{% endif %}
 <dt>{% trans "Begin date" %}</dt><dd>{{ media.conference.date_begin }}</dd>
index 2fa6fc106ceb97919b8f16ffcb2ef8c395969ac4..50171ad839647dc93bd6b0dd7bcc9ab0848a3dba 100644 (file)
@@ -92,9 +92,9 @@ $(document).ready(function(){
 {% if media.conference %}
 <dt>{% trans "Course" %}</dt><dd><a href="{% url 'teleforma-desk-period-course' period.id course.id %}">{{ media.course.title }} - {{ media.course_type }}</a></dd>
 <dt>{% trans "Session" %}</dt><dd>{{ media.conference.session }}</dd>
-{% if media.conference.professor %}
-<dt>{% trans "Professor" %}</dt>
-    <dd><a href="{% url 'teleforma-profile-detail' media.conference.professor.user.username %}" target="_blank">{{ media.conference.professor }}</a></dd>
+{% if media.conference.professor.all %}
+<dt>{% if media.conference.professor.count > 1 %}{% trans "Professors" %}{% else %}{% trans "Professor" %}{% endif %}</dt>
+    <dd>{% for professor in media.conference.professor.all %}<a href="{% url 'teleforma-profile-detail' professor.user.username %}" target="_blank">{{ professor }}</a>{% if not forloop.last %}, {% endif %}{% endfor %}</dd>
 {% endif %}
 {% if media.conference.comment %}<dt>{% trans "Comment" %}</dt><dd>{{ media.conference.comment }}</dd>{% endif %}
 <dt>{% trans "Begin date" %}</dt><dd>{{ media.conference.date_begin }}</dd>
index 0bfe1827fb4ac17962270a50235cf1c3ee37ea45..eab3d7eaf497f0b3f5c536286b545a234122b135 100644 (file)
     <div class="course_content" id="media_infos">
         <dl class="listing">
 
-            {% if conference.professor %}
+            {% if conference.professor.all %}
             <dt>{% trans "Course" %}</dt>
             <dd><a href="{% url 'teleforma-course-detail' course.id %}">{{ conference.course.title }}{% if conference.course_type != None %}
                     - {{ conference.course_type }}{% endif %}</a></dd>
             <dt>Niveau</dt>
             <dd>{{ conference.level }}</dd>
-            <dt>{% trans "Professor" %}</dt>
-            <dd><a href="{% url 'teleforma-profile-detail' conference.professor.user.username %}"
-                    target="_blank">{{ conference.professor }}</a></dd>
+            <dt>{% if conference.professor.count > 1 %}{% trans "Professors" %}{% else %}{% trans "Professor" %}{% endif %}</dt>
+            <dd>{% for professor in conference.professor.all %}<a href="{% url 'teleforma-profile-detail' professor.user.username %}"
+                    target="_blank">{{ professor }}</a>{% if not forloop.last %}, {% endif %}{% endfor %}</dd>
             {% endif %}
             {% if conference.comment %}<dt>{% trans "Comment" %}</dt>
             <dd>{{ conference.comment }}</dd>{% endif %}
index 0bc22c36d2763d528b7a6b35aa3225d5d166c088..0f3cec029f54a9da7e5917f45c0e6be9e2b80e26 100644 (file)
@@ -24,7 +24,7 @@
                     <dl class="listing" style="font-size: 1.2em;">
                     <dt>{% trans "Title" %}</dt><dd>{{ stream.conference.course.title }}</dd>
                     <dt>{% trans "Session" %}</dt><dd>{{ stream.conference.session }}</dd>
-                    <dt>{% trans "Professor" %}</dt><dd><a href="{% url 'teleforma-profile-detail' stream.conference.professor.user.username %}" target="_blank">{{ stream.conference.professor }}</a></dd>
+                    <dt>{% if stream.conference.professor.count > 1 %}{% trans "Professors" %}{% else %}{% trans "Professor" %}{% endif %}</dt><dd>{% for professor in stream.conference.professor.all %}<a href="{% url 'teleforma-profile-detail' professor.user.username %}" target="_blank">{{ professor }}</a>{% if not forloop.last %}, {% endif %}{% endfor %}</dd>
                     <dt>{% trans "Begin" %}</dt><dd>{{ stream.conference.date_begin }}</dd>
                     </dl>
                  </div>
index 51fdd6d2ff0df6a2d1236ce55f3331b17f021228..b225ff203f844464714b0a80266c1968d8177ae9 100644 (file)
@@ -31,8 +31,8 @@
                     <dl class="listing" style="font-size: 1.2em;">
                     <dt>{% trans "Title" %}</dt><dd>{{ media.conference.course.title }}</dd>
                     <dt>{% trans "Session" %}</dt><dd>{{ media.conference.session }}</dd>
-                    {% if media.conference.professor %}
-                    <dt>{% trans "Professor" %}</dt><dd><a href="{% url 'teleforma-profile-detail' media.conference.professor.user.username %}" target="_blank">{{ media.conference.professor }}</a></dd>
+                    {% if media.conference.professor.all %}
+                    <dt>{% if media.conference.professor.count > 1 %}{% trans "Professors" %}{% else %}{% trans "Professor" %}{% endif %}</dt><dd>{% for professor in media.conference.professor.all %}<a href="{% url 'teleforma-profile-detail' professor.user.username %}" target="_blank">{{ professor }}</a>{% if not forloop.last %}, {% endif %}{% endfor %}</dd>
                     {% endif %}
                     <dt>{% trans "Begin" %}</dt><dd>{{ media.conference.date_begin }}</dd>
                     {% if media.conference.comment %}
index fbf11d0412a37b0ac9444f273ec4a1d623cae0a4..28c788a94216e20377b57e25837dabf6559b77fb 100644 (file)
@@ -680,16 +680,19 @@ class ConferenceRecordView(FormView):
                                                        course=course, course_type=course_type)
             if c:
                 conf.session = conference['session']
-                if conference['professor_id']:
-                    user = User.objects.filter(username=conference['professor_id'])
+                professor_ids = conference.get('professor_ids') or []
+                if not professor_ids and conference['professor_id']:
+                    professor_ids = [conference['professor_id']]
+                for professor_id in professor_ids:
+                    user = User.objects.filter(username=professor_id)
                     if user:
-                        conf.professor = Professor.objects.get(user=user[0])
+                        professor = Professor.objects.get(user=user[0])
                     else:
-                        user = User(username=conference['professor_id'])
+                        user = User(username=professor_id)
                         user.save()
                         professor = Professor(user=user)
                         professor.save()
-                        conf.professor = professor
+                    conf.professor.add(professor)
                 try:
                     organization, c = Organization.objects.get_or_create(name=conference['organization'])
                     conf.room, c = Room.objects.get_or_create(name=conference['room'],