diff --git a/mo/db.py b/mo/db.py
index deb67a4012ea97a5427d9c9accda607b68255c73..76c6aa3c1e5ee1b48365d95b95eb248a5e958ebb 100644
--- a/mo/db.py
+++ b/mo/db.py
@@ -416,6 +416,9 @@ class User(Base):
     def full_name(self) -> str:
         return self.first_name + ' ' + self.last_name
 
+    def full_email(self) -> str:
+        return f'{self.first_name} {self.last_name} <{self.email}>'
+
     def sort_key(self) -> Tuple[str, str, int]:
         return (locale.strxfrm(self.last_name), locale.strxfrm(self.first_name), self.user_id)
 
diff --git a/mo/web/org_contest.py b/mo/web/org_contest.py
index 6f57771b00183fcb951ee0008b49c39383bcd3ef..6bbc463d1287bc56f83a29499f6dd8c1dd30d906 100644
--- a/mo/web/org_contest.py
+++ b/mo/web/org_contest.py
@@ -275,6 +275,9 @@ class ParticipantsFilterForm(PagerForm):
     contest_place = mo_fields.Place("Soutěžní oblast", render_kw={'autofocus': True})
     participation_state = wtforms.SelectField('Stav účasti', choices=[('*', '*')] + list(db.PartState.choices()), default='*')
 
+    pant_email = wtforms.BooleanField("E-maily účastníků", default=True)
+    school_email = wtforms.BooleanField("E-maily jejich školních garantů", default=False)
+
     # format = wtforms.RadioField(choices=[('', 'Zobrazit'), ('csv', 'Stáhnout vše v CSV'), ('tsv', 'Stáhnout vše v TSV')])
     submit = wtforms.SubmitField("Zobrazit")
     download_csv = wtforms.SubmitField("↓ CSV")
@@ -545,7 +548,7 @@ def org_import_org(round_id: Optional[int] = None, hier_id: Optional[int] = None
         contest=contest,
         round=round,
         default_place=default_place
-        )
+    )
 
 
 # URL je explicitně uvedeno v mo.email.contestant_list_url
@@ -565,7 +568,8 @@ def org_generic_list(round_id: Optional[int] = None, hier_id: Optional[int] = No
     can_edit = rr.have_right(Right.manage_contest) and request.endpoint != 'org_generic_list_emails'
     format = request.args.get('format', "")
 
-    filter = ParticipantsFilterForm(formdata=request.args)
+    # XXX: Předáme-li prázdný slovník jako request.args, zresetují se booleovská políčka
+    filter = ParticipantsFilterForm(formdata=request.args if request.args else None)
     if request.args:
         filter.validate()
 
@@ -587,13 +591,17 @@ def org_generic_list(round_id: Optional[int] = None, hier_id: Optional[int] = No
     if format == "":
         table = None
         emails = None
+        missing_org_warnings = None
         mailto_link = None
         if request.endpoint == 'org_generic_list_emails':
             if contest:
                 subj = f'{contest.round.name} {contest.round.category} {contest.place.name_locative()}'
             else:
                 subj = f'{round.name} kategorie {round.category}'
-            (emails, mailto_link) = get_contestant_emails(query, mailto_subject=subj)
+            (emails, mailto_link, missing_org_warnings) = \
+                get_contestant_emails(query, mailto_subject=subj,
+                                      pant_email=filter.pant_email.data,
+                                      school_email=filter.school_email.data)
             count = len(emails)
         else:
             (count, query) = filter.apply_limits(query, pagesize=50)
@@ -605,9 +613,10 @@ def org_generic_list(round_id: Optional[int] = None, hier_id: Optional[int] = No
             contest=contest, round=round, site=ctx.site,
             table=table, emails=emails, mailto_link=mailto_link,
             filter=filter, count=count, action_form=action_form,
+            missing_org_warnings=missing_org_warnings,
         )
     else:
-        table = make_contestant_table(query, round)
+        table = make_contestant_table(query, round, add_school_orgs=True)
         return table.send_as(format, args=request.args)
 
 
@@ -618,6 +627,7 @@ contest_list_columns = (
     Column(key='email',         name='email',       title='E-mail'),
     Column(key='school',        name='skola',       title='Škola'),
     Column(key='school_code',   name='kod_skoly',   title='Kód školy'),
+    Column(key='school_orgs',   name='skol_garanti', title='E-maily školních garantů'),
     Column(key='grade',         name='rocnik',      title='Ročník'),
     Column(key='born_year',     name='rok_naroz',   title='Rok naroz.'),
     Column(key='place_code',    name='kod_soutez_mista',  title='Sout. místo'),
@@ -665,33 +675,55 @@ def get_contestants_query(
     return query
 
 
-def make_contestant_table(query: Query, round: db.Round, add_checkbox: bool = False, add_contest_column: bool = False):
+def get_school_orgs(query_result: List[Tuple[db.Participation, db.Participant, db.Contest]]) -> Dict[int, List[db.User]]:
+    school_ids = set(pant.school for _, pant, _ in query_result)
+
+    user_roles = (db.get_session()
+                  .query(db.UserRole)
+                  .filter_by(role=db.RoleType.garant_skola)
+                  .filter(db.UserRole.place_id.in_(school_ids))
+                  .options(joinedload(db.UserRole.user))
+                  .all())
+
+    out: Dict[int, List[db.User]] = {sid: [] for sid in school_ids}
+
+    for ur in user_roles:
+        out[ur.place_id].append(ur.user)
+
+    return out
+
+
+def make_contestant_table(query: Query, round: db.Round, add_checkbox: bool = False, add_contest_column: bool = False, add_school_orgs: bool = False) -> Table:
     ctants = query.all()
 
+    if add_school_orgs:
+        school_orgs = get_school_orgs(ctants)
+
     rows: List[Row] = []
     for pion, pant, ct in ctants:
         u = pion.user
         html_attr = {
             'class': 'state-' + pion.state.name
         }
-        rows.append(Row(
-            keys={
-                'sort_key': u.sort_key(),
-                'user_id': u.user_id,
-                'first_name': cell_pion_link(u, pion.contest_id, u.first_name),
-                'last_name': cell_pion_link(u, pion.contest_id, u.last_name),
-                'email': cell_email_link_flags(u),
-                'school': pant.school_place.name,
-                'school_code': cell_place_link(pant.school_place),
-                'grade': pant.grade,
-                'born_year': pant.birth_year,
-                'region_code': cell_contest_link(ct),
-                'place_code': cell_contest_link(ct, pion.place),
-                'status': pion.state.friendly_name(),
-                'checkbox': CellCheckbox('checked', u.user_id, False),
-            },
-            html_attr=html_attr,
-        ))
+        row_keys = {
+            'sort_key': u.sort_key(),
+            'user_id': u.user_id,
+            'first_name': cell_pion_link(u, pion.contest_id, u.first_name),
+            'last_name': cell_pion_link(u, pion.contest_id, u.last_name),
+            'email': cell_email_link_flags(u),
+            'school': pant.school_place.name,
+            'school_code': cell_place_link(pant.school_place),
+            'grade': pant.grade,
+            'born_year': pant.birth_year,
+            'region_code': cell_contest_link(ct),
+            'place_code': cell_contest_link(ct, pion.place),
+            'status': pion.state.friendly_name(),
+            'checkbox': CellCheckbox('checked', u.user_id, False),
+        }
+        if add_school_orgs:
+            assert pant.school in school_orgs
+            row_keys['school_orgs'] = ', '.join([user.email for user in school_orgs[pant.school]])
+        rows.append(Row(keys=row_keys, html_attr=html_attr))
 
     rows.sort(key=lambda r: r.keys['sort_key'])
 
@@ -710,15 +742,40 @@ def make_contestant_table(query: Query, round: db.Round, add_checkbox: bool = Fa
     )
 
 
-def get_contestant_emails(query: Query, mailto_subject: str = '[OSMO] Zpráva pro účastníky') -> Tuple[List[str], str]:
-    users = [pion.user for (pion, _, _) in query.all()]
-    emails = [f'{u.first_name} {u.last_name} <{u.email}>' for u in users]
+def get_contestant_emails(query: Query,
+                          mailto_subject: str,
+                          pant_email: bool = True,
+                          school_email: bool = True,
+                          ) -> Tuple[List[str], str, List[str]]:
+    ctants = query.all()
+
+    user_set: Set[db.User]
+    if pant_email:
+        user_set = set(pion.user for (pion, _, _) in ctants)
+    else:
+        user_set = set()
+
+    org_warning_for: List[db.User] = []
+    if school_email:
+        school_orgs = get_school_orgs(ctants)
+        for pion, pant, _ in ctants:
+            if school_orgs[pant.school]:
+                for u in school_orgs[pant.school]:
+                    user_set.add(u)
+            else:
+                org_warning_for.append(pion.user)
+
+    users = sorted(user_set, key=lambda u: u.sort_key())
+    emails = [u.full_email() for u in users]
+    org_warnings = [u.full_name() for u in sorted(org_warning_for, key=lambda u: u.sort_key())]
+
     mailto_link = (
-        'mailto:' + urllib.parse.quote(config.MAIL_CONTACT, safe='@')
+        'mailto:' + urllib.parse.quote(g.user.full_email(), safe='@')
         + '?subject=' + urllib.parse.quote(mailto_subject)
-        + '&bcc=' + ','.join([urllib.parse.quote(email, safe='@') for email in emails])
+        + '&bcc=' + ','.join([urllib.parse.quote(u.email, safe='@') for u in users])
     )
-    return (emails, mailto_link)
+
+    return (emails, mailto_link, org_warnings)
 
 
 class SubmitForm(FlaskForm):
diff --git a/mo/web/table.py b/mo/web/table.py
index 65fdde48fd4f6f65e15967102760dd351c0283ff..bc6975f587a3f1637b1628d84acb65e33c920667 100644
--- a/mo/web/table.py
+++ b/mo/web/table.py
@@ -6,7 +6,7 @@ import io
 from markupsafe import Markup
 from typing import Any, Dict, List, Sequence, Optional, Iterable, Union
 import urllib.parse
-from werkzeug.datastructures import ImmutableMultiDict
+from werkzeug.datastructures import MultiDict, ImmutableMultiDict
 import werkzeug.exceptions
 
 from mo.csv import FileFormat
@@ -206,7 +206,7 @@ class Table:
 
         return Markup("\n".join(tab))
 
-    def get_columns_checkboxes(self, line_prefix: str = "", args: Optional[ImmutableMultiDict] = None) -> Markup:
+    def get_columns_checkboxes(self, line_prefix: str = "", args: Union[None, MultiDict, ImmutableMultiDict] = None) -> Markup:
         out = [line_prefix + '<input type="hidden" name="do_column_selection" value="1">']
         for c in self.columns:
             if c.in_export is None:
@@ -251,7 +251,7 @@ class Table:
 
         yield out.getvalue().encode(fmt.get_charset())
 
-    def send_as(self, format: Union[FileFormat, str], streaming: bool = False, args: Optional[ImmutableMultiDict] = None) -> Response:
+    def send_as(self, format: Union[FileFormat, str], streaming: bool = False, args: Union[None, MultiDict, ImmutableMultiDict] = None) -> Response:
         try:
             fmt = FileFormat.coerce(format)
         except ValueError:
diff --git a/mo/web/templates/org_generic_list.html b/mo/web/templates/org_generic_list.html
index cddfcda9cbc408667feae0aee9b4b18d0841aad1..854df8042880b21271ce943a6ceae728afbec00d 100644
--- a/mo/web/templates/org_generic_list.html
+++ b/mo/web/templates/org_generic_list.html
@@ -27,6 +27,13 @@
 		{{ wtf.form_field(filter.school, size=8) }}
 		{{ wtf.form_field(filter.participation_state) }}
 	</div>
+	{% if not table %}
+		{{ wtf.form_field(filter.pant_email) }}
+		&nbsp;
+		{{ wtf.form_field(filter.school_email) }}
+	<div>
+	</div>
+	{% endif %}
 	<div class="form-row" style="margin-top: 5px;">
 		<div class="btn-group">
 			{{ wtf.form_field(filter.submit, class='btn btn-primary') }}
@@ -146,6 +153,11 @@
 	</p>
 	{% endif %}
 {% else %}
+	{% if missing_org_warnings %}
+	<h3>Školní garant nenalezen pro tyto účastníky:</h3>
+	<pre>{{ missing_org_warnings|join('\n')|escape }}</pre>
+	{% endif %}
+
 	<h3>E-mailové adresy</h3>
 
 	{% if emails %}
diff --git a/mo/web/templates/parts/org_contest_guide.html b/mo/web/templates/parts/org_contest_guide.html
index f8f23ddd13a7dae496fcb431d6458aab7a3930d1..9d425c5879348faa89986fd033ef3103f1dd023e 100644
--- a/mo/web/templates/parts/org_contest_guide.html
+++ b/mo/web/templates/parts/org_contest_guide.html
@@ -27,7 +27,7 @@
 	{% endif %}
 
 	{% if round_type not in [RoundType.domaci, RoundType.skolni] %}
-	<li>Rozešlete soutěžícím <a href='{{ ctx.url_for('org_generic_list_emails') }}'>pozvánky</a>.
+	<li>Rozešlete soutěžícím <a href='{{ ctx.url_for('org_generic_list_emails', participation_state='active', pant_email=True, school_email=True) }}'>pozvánky</a>.
 	{% endif %}
 
 	{% if round_type != RoundType.domaci %}