prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Improve the user search and selection form
  In #1684 the user selection for groups was consolidated, so now it would be good to improve it. The form uses a ModelSelect2 widget (https://github.com/comic/grand-challenge.org/blob/master/app/grandchallenge/groups/forms.py#L19) that calls an autocomplete view that only allows filtering by username (https://github.com/comic/grand-challenge.org/blob/master/app/grandchallenge/groups/views.py#L67). 
  
  Top priority is to extend the filter:
  - Switch to filtering with `icontains` rather than `istartswith`
  - Allow filtering on the users username, email address, full name, OR verification email address. To do this use Django `Q` objects (https://docs.djangoproject.com/en/3.1/topics/db/queries/#complex-lookups-with-q-objects).
  
  Next, is to improve the look of the widget, at the moment you just get a string of the username:
  ![image](https://user-images.githubusercontent.com/12661555/105184656-e1834880-5b2f-11eb-9ac7-36c9e2fcff22.png)
  
  On github it's much nicer
  ![image](https://user-images.githubusercontent.com/12661555/105184861-214a3000-5b30-11eb-9fe5-24aa1c4613a4.png)
  
  Extend this to
  - Include the users full name in the string
  - Show whether the user is verified or not in the string, and if so, what is the domain of their verification address (see https://github.com/comic/grand-challenge.org/blob/master/app/grandchallenge/profiles/templatetags/profiles.py#L16)
  - Stretch goal: Show the users mugshot
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `app/grandchallenge/groups/forms.py`
  Content:
  ```
  1 from dal import autocomplete
  2 from django.conf import settings
  3 from django.contrib.auth import get_user_model
  4 from django.core.exceptions import ValidationError
  5 from django.forms import ChoiceField, Form, HiddenInput, ModelChoiceField
  6 from guardian.utils import get_anonymous_user
  7 
  8 from grandchallenge.core.forms import SaveFormInitMixin
  9 
  10 
  11 class UserGroupForm(SaveFormInitMixin, Form):
  12     ADD = "ADD"
  13     REMOVE = "REMOVE"
  14     CHOICES = ((ADD, "Add"), (REMOVE, "Remove"))
  15     user = ModelChoiceField(
  16         queryset=get_user_model().objects.all().order_by("username"),
  17         help_text="Select a user that will be added to the group",
  18         required=True,
  19         widget=autocomplete.ModelSelect2(
  20             url="users-autocomplete",
  21             attrs={
  22                 "data-placeholder": "Search for a user ...",
  23                 "data-minimum-input-length": 3,
  24                 "data-theme": settings.CRISPY_TEMPLATE_PACK,
  25             },
  26         ),
  27     )
  28     action = ChoiceField(
  29         choices=CHOICES, required=True, widget=HiddenInput(), initial=ADD
  30     )
  31 
  32     def clean_user(self):
  33         user = self.cleaned_data["user"]
  34         if user == get_anonymous_user():
  35             raise ValidationError("You cannot add this user!")
  36         return user
  37 
  38     def add_or_remove_user(self, *, obj):
  39         if self.cleaned_data["action"] == self.ADD:
  40             getattr(obj, f"add_{self.role}")(self.cleaned_data["user"])
  41         elif self.cleaned_data["action"] == self.REMOVE:
  42             getattr(obj, f"remove_{self.role}")(self.cleaned_data["user"])
  43 
  44 
  45 class EditorsForm(UserGroupForm):
  46     role = "editor"
  47 
  48 
  49 class MembersForm(UserGroupForm):
  50     role = "member"
  51 
  52 
  53 class UsersForm(UserGroupForm):
  54     role = "user"
  55
  ```
  
  Path: `app/grandchallenge/groups/views.py`
  Content:
  ```
  1 from dal import autocomplete
  2 from django.conf import settings
  3 from django.contrib.auth import get_user_model
  4 from django.contrib.auth.mixins import UserPassesTestMixin
  5 from django.contrib.messages.views import SuccessMessageMixin
  6 from django.views.generic import FormView
  7 from guardian.mixins import (
  8     LoginRequiredMixin,
  9     PermissionRequiredMixin as ObjectPermissionRequiredMixin,
  10 )
  11 from guardian.shortcuts import get_objects_for_user
  12 
  13 
  14 class UserGroupUpdateMixin(
  15     LoginRequiredMixin,
  16     ObjectPermissionRequiredMixin,
  17     SuccessMessageMixin,
  18     FormView,
  19 ):
  20     raise_exception = True
  21 
  22     def get_permission_object(self):
  23         return self.obj
  24 
  25     @property
  26     def obj(self):
  27         raise NotImplementedError
  28 
  29     def get_context_data(self, **kwargs):
  30         context = super().get_context_data(**kwargs)
  31         context.update({"object": self.obj, "role": self.get_form().role})
  32         return context
  33 
  34     def get_success_url(self):
  35         return self.obj.get_absolute_url()
  36 
  37     def form_valid(self, form):
  38         form.add_or_remove_user(obj=self.obj)
  39         return super().form_valid(form)
  40 
  41 
  42 class UserAutocomplete(
  43     LoginRequiredMixin, UserPassesTestMixin, autocomplete.Select2QuerySetView
  44 ):
  45     def test_func(self):
  46         allowed_perms = [
  47             "algorithms.change_algorithm",
  48             "organizations.change_organization",
  49             "archives.change_archive",
  50             "reader_studies.change_readerstudy",
  51             "workstations.change_workstation",
  52             "algorithms.change_job",
  53         ]
  54         return any(
  55             get_objects_for_user(user=self.request.user, perms=perm,).exists()
  56             for perm in allowed_perms
  57         )
  58 
  59     def get_queryset(self):
  60         qs = (
  61             get_user_model()
  62             .objects.order_by("username")
  63             .exclude(username=settings.ANONYMOUS_USER_NAME)
  64         )
  65 
  66         if self.q:
  67             qs = qs.filter(username__istartswith=self.q)
  68 
  69         return qs
  70
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/app/grandchallenge/groups/forms.py b/app/grandchallenge/groups/forms.py
  --- a/app/grandchallenge/groups/forms.py
  +++ b/app/grandchallenge/groups/forms.py
  @@ -22,6 +22,7 @@
                   "data-placeholder": "Search for a user ...",
                   "data-minimum-input-length": 3,
                   "data-theme": settings.CRISPY_TEMPLATE_PACK,
  +                "data-html": True,
               },
           ),
       )
  diff --git a/app/grandchallenge/groups/views.py b/app/grandchallenge/groups/views.py
  --- a/app/grandchallenge/groups/views.py
  +++ b/app/grandchallenge/groups/views.py
  @@ -3,6 +3,9 @@
   from django.contrib.auth import get_user_model
   from django.contrib.auth.mixins import UserPassesTestMixin
   from django.contrib.messages.views import SuccessMessageMixin
  +from django.db.models import CharField, Q, Value
  +from django.db.models.functions import Concat
  +from django.utils.html import format_html
   from django.views.generic import FormView
   from guardian.mixins import (
       LoginRequiredMixin,
  @@ -10,6 +13,8 @@
   )
   from guardian.shortcuts import get_objects_for_user
   
  +from grandchallenge.verifications.models import Verification
  +
   
   class UserGroupUpdateMixin(
       LoginRequiredMixin,
  @@ -51,6 +56,7 @@
               "workstations.change_workstation",
               "algorithms.change_job",
           ]
  +        # TODO reduce number of queries
           return any(
               get_objects_for_user(user=self.request.user, perms=perm,).exists()
               for perm in allowed_perms
  @@ -61,9 +67,50 @@
               get_user_model()
               .objects.order_by("username")
               .exclude(username=settings.ANONYMOUS_USER_NAME)
  +            .annotate(
  +                full_name=Concat(
  +                    "first_name",
  +                    Value(" "),
  +                    "last_name",
  +                    output_field=CharField(),
  +                )
  +            )
  +            .select_related("verification", "user_profile")
           )
   
           if self.q:
  -            qs = qs.filter(username__istartswith=self.q)
  +            qs = qs.filter(
  +                Q(username__icontains=self.q)
  +                | Q(email__icontains=self.q)
  +                | Q(full_name__icontains=self.q)
  +                | Q(verification__email__icontains=self.q)
  +            )
   
           return qs
  +
  +    def get_result_label(self, result):
  +
  +        try:
  +            is_verified = result.verification.is_verified
  +        except Verification.DoesNotExist:
  +            is_verified = False
  +
  +        if is_verified:
  +            return format_html(
  +                '<img src="{}" width ="20" height ="20" style="vertical-align:top"> '
  +                "&nbsp; <b>{}</b> &nbsp; {} &nbsp;"
  +                '<i class="fas fa-user-check text-success" '
  +                'title="Verified email address at {}">',
  +                result.user_profile.get_mugshot_url(),
  +                result.get_username(),
  +                result.get_full_name().title(),
  +                result.verification.email.split("@")[1],
  +            )
  +        else:
  +            return format_html(
  +                '<img src="{}" width ="20" height ="20" style="vertical-align:top"> '
  +                "&nbsp; <b>{}</b> &nbsp; {}",
  +                result.user_profile.get_mugshot_url(),
  +                result.get_username(),
  +                result.get_full_name().title(),
  +            )
  
verification_info: {"golden_diff": "diff --git a/app/grandchallenge/groups/forms.py b/app/grandchallenge/groups/forms.py\n--- a/app/grandchallenge/groups/forms.py\n+++ b/app/grandchallenge/groups/forms.py\n@@ -22,6 +22,7 @@\n                 \"data-placeholder\": \"Search for a user ...\",\n                 \"data-minimum-input-length\": 3,\n                 \"data-theme\": settings.CRISPY_TEMPLATE_PACK,\n+                \"data-html\": True,\n             },\n         ),\n     )\ndiff --git a/app/grandchallenge/groups/views.py b/app/grandchallenge/groups/views.py\n--- a/app/grandchallenge/groups/views.py\n+++ b/app/grandchallenge/groups/views.py\n@@ -3,6 +3,9 @@\n from django.contrib.auth import get_user_model\n from django.contrib.auth.mixins import UserPassesTestMixin\n from django.contrib.messages.views import SuccessMessageMixin\n+from django.db.models import CharField, Q, Value\n+from django.db.models.functions import Concat\n+from django.utils.html import format_html\n from django.views.generic import FormView\n from guardian.mixins import (\n     LoginRequiredMixin,\n@@ -10,6 +13,8 @@\n )\n from guardian.shortcuts import get_objects_for_user\n \n+from grandchallenge.verifications.models import Verification\n+\n \n class UserGroupUpdateMixin(\n     LoginRequiredMixin,\n@@ -51,6 +56,7 @@\n             \"workstations.change_workstation\",\n             \"algorithms.change_job\",\n         ]\n+        # TODO reduce number of queries\n         return any(\n             get_objects_for_user(user=self.request.user, perms=perm,).exists()\n             for perm in allowed_perms\n@@ -61,9 +67,50 @@\n             get_user_model()\n             .objects.order_by(\"username\")\n             .exclude(username=settings.ANONYMOUS_USER_NAME)\n+            .annotate(\n+                full_name=Concat(\n+                    \"first_name\",\n+                    Value(\" \"),\n+                    \"last_name\",\n+                    output_field=CharField(),\n+                )\n+            )\n+            .select_related(\"verification\", \"user_profile\")\n         )\n \n         if self.q:\n-            qs = qs.filter(username__istartswith=self.q)\n+            qs = qs.filter(\n+                Q(username__icontains=self.q)\n+                | Q(email__icontains=self.q)\n+                | Q(full_name__icontains=self.q)\n+                | Q(verification__email__icontains=self.q)\n+            )\n \n         return qs\n+\n+    def get_result_label(self, result):\n+\n+        try:\n+            is_verified = result.verification.is_verified\n+        except Verification.DoesNotExist:\n+            is_verified = False\n+\n+        if is_verified:\n+            return format_html(\n+                '<img src=\"{}\" width =\"20\" height =\"20\" style=\"vertical-align:top\"> '\n+                \"&nbsp; <b>{}</b> &nbsp; {} &nbsp;\"\n+                '<i class=\"fas fa-user-check text-success\" '\n+                'title=\"Verified email address at {}\">',\n+                result.user_profile.get_mugshot_url(),\n+                result.get_username(),\n+                result.get_full_name().title(),\n+                result.verification.email.split(\"@\")[1],\n+            )\n+        else:\n+            return format_html(\n+                '<img src=\"{}\" width =\"20\" height =\"20\" style=\"vertical-align:top\"> '\n+                \"&nbsp; <b>{}</b> &nbsp; {}\",\n+                result.user_profile.get_mugshot_url(),\n+                result.get_username(),\n+                result.get_full_name().title(),\n+            )\n", "issue": "Improve the user search and selection form\nIn #1684 the user selection for groups was consolidated, so now it would be good to improve it. The form uses a ModelSelect2 widget (https://github.com/comic/grand-challenge.org/blob/master/app/grandchallenge/groups/forms.py#L19) that calls an autocomplete view that only allows filtering by username (https://github.com/comic/grand-challenge.org/blob/master/app/grandchallenge/groups/views.py#L67). \r\n\r\nTop priority is to extend the filter:\r\n- Switch to filtering with `icontains` rather than `istartswith`\r\n- Allow filtering on the users username, email address, full name, OR verification email address. To do this use Django `Q` objects (https://docs.djangoproject.com/en/3.1/topics/db/queries/#complex-lookups-with-q-objects).\r\n\r\nNext, is to improve the look of the widget, at the moment you just get a string of the username:\r\n![image](https://user-images.githubusercontent.com/12661555/105184656-e1834880-5b2f-11eb-9ac7-36c9e2fcff22.png)\r\n\r\nOn github it's much nicer\r\n![image](https://user-images.githubusercontent.com/12661555/105184861-214a3000-5b30-11eb-9fe5-24aa1c4613a4.png)\r\n\r\nExtend this to\r\n- Include the users full name in the string\r\n- Show whether the user is verified or not in the string, and if so, what is the domain of their verification address (see https://github.com/comic/grand-challenge.org/blob/master/app/grandchallenge/profiles/templatetags/profiles.py#L16)\r\n- Stretch goal: Show the users mugshot\r\n\n", "before_files": [{"content": "from dal import autocomplete\nfrom django.conf import settings\nfrom django.contrib.auth import get_user_model\nfrom django.core.exceptions import ValidationError\nfrom django.forms import ChoiceField, Form, HiddenInput, ModelChoiceField\nfrom guardian.utils import get_anonymous_user\n\nfrom grandchallenge.core.forms import SaveFormInitMixin\n\n\nclass UserGroupForm(SaveFormInitMixin, Form):\n    ADD = \"ADD\"\n    REMOVE = \"REMOVE\"\n    CHOICES = ((ADD, \"Add\"), (REMOVE, \"Remove\"))\n    user = ModelChoiceField(\n        queryset=get_user_model().objects.all().order_by(\"username\"),\n        help_text=\"Select a user that will be added to the group\",\n        required=True,\n        widget=autocomplete.ModelSelect2(\n            url=\"users-autocomplete\",\n            attrs={\n                \"data-placeholder\": \"Search for a user ...\",\n                \"data-minimum-input-length\": 3,\n                \"data-theme\": settings.CRISPY_TEMPLATE_PACK,\n            },\n        ),\n    )\n    action = ChoiceField(\n        choices=CHOICES, required=True, widget=HiddenInput(), initial=ADD\n    )\n\n    def clean_user(self):\n        user = self.cleaned_data[\"user\"]\n        if user == get_anonymous_user():\n            raise ValidationError(\"You cannot add this user!\")\n        return user\n\n    def add_or_remove_user(self, *, obj):\n        if self.cleaned_data[\"action\"] == self.ADD:\n            getattr(obj, f\"add_{self.role}\")(self.cleaned_data[\"user\"])\n        elif self.cleaned_data[\"action\"] == self.REMOVE:\n            getattr(obj, f\"remove_{self.role}\")(self.cleaned_data[\"user\"])\n\n\nclass EditorsForm(UserGroupForm):\n    role = \"editor\"\n\n\nclass MembersForm(UserGroupForm):\n    role = \"member\"\n\n\nclass UsersForm(UserGroupForm):\n    role = \"user\"\n", "path": "app/grandchallenge/groups/forms.py"}, {"content": "from dal import autocomplete\nfrom django.conf import settings\nfrom django.contrib.auth import get_user_model\nfrom django.contrib.auth.mixins import UserPassesTestMixin\nfrom django.contrib.messages.views import SuccessMessageMixin\nfrom django.views.generic import FormView\nfrom guardian.mixins import (\n    LoginRequiredMixin,\n    PermissionRequiredMixin as ObjectPermissionRequiredMixin,\n)\nfrom guardian.shortcuts import get_objects_for_user\n\n\nclass UserGroupUpdateMixin(\n    LoginRequiredMixin,\n    ObjectPermissionRequiredMixin,\n    SuccessMessageMixin,\n    FormView,\n):\n    raise_exception = True\n\n    def get_permission_object(self):\n        return self.obj\n\n    @property\n    def obj(self):\n        raise NotImplementedError\n\n    def get_context_data(self, **kwargs):\n        context = super().get_context_data(**kwargs)\n        context.update({\"object\": self.obj, \"role\": self.get_form().role})\n        return context\n\n    def get_success_url(self):\n        return self.obj.get_absolute_url()\n\n    def form_valid(self, form):\n        form.add_or_remove_user(obj=self.obj)\n        return super().form_valid(form)\n\n\nclass UserAutocomplete(\n    LoginRequiredMixin, UserPassesTestMixin, autocomplete.Select2QuerySetView\n):\n    def test_func(self):\n        allowed_perms = [\n            \"algorithms.change_algorithm\",\n            \"organizations.change_organization\",\n            \"archives.change_archive\",\n            \"reader_studies.change_readerstudy\",\n            \"workstations.change_workstation\",\n            \"algorithms.change_job\",\n        ]\n        return any(\n            get_objects_for_user(user=self.request.user, perms=perm,).exists()\n            for perm in allowed_perms\n        )\n\n    def get_queryset(self):\n        qs = (\n            get_user_model()\n            .objects.order_by(\"username\")\n            .exclude(username=settings.ANONYMOUS_USER_NAME)\n        )\n\n        if self.q:\n            qs = qs.filter(username__istartswith=self.q)\n\n        return qs\n", "path": "app/grandchallenge/groups/views.py"}], "after_files": [{"content": "from dal import autocomplete\nfrom django.conf import settings\nfrom django.contrib.auth import get_user_model\nfrom django.core.exceptions import ValidationError\nfrom django.forms import ChoiceField, Form, HiddenInput, ModelChoiceField\nfrom guardian.utils import get_anonymous_user\n\nfrom grandchallenge.core.forms import SaveFormInitMixin\n\n\nclass UserGroupForm(SaveFormInitMixin, Form):\n    ADD = \"ADD\"\n    REMOVE = \"REMOVE\"\n    CHOICES = ((ADD, \"Add\"), (REMOVE, \"Remove\"))\n    user = ModelChoiceField(\n        queryset=get_user_model().objects.all().order_by(\"username\"),\n        help_text=\"Select a user that will be added to the group\",\n        required=True,\n        widget=autocomplete.ModelSelect2(\n            url=\"users-autocomplete\",\n            attrs={\n                \"data-placeholder\": \"Search for a user ...\",\n                \"data-minimum-input-length\": 3,\n                \"data-theme\": settings.CRISPY_TEMPLATE_PACK,\n                \"data-html\": True,\n            },\n        ),\n    )\n    action = ChoiceField(\n        choices=CHOICES, required=True, widget=HiddenInput(), initial=ADD\n    )\n\n    def clean_user(self):\n        user = self.cleaned_data[\"user\"]\n        if user == get_anonymous_user():\n            raise ValidationError(\"You cannot add this user!\")\n        return user\n\n    def add_or_remove_user(self, *, obj):\n        if self.cleaned_data[\"action\"] == self.ADD:\n            getattr(obj, f\"add_{self.role}\")(self.cleaned_data[\"user\"])\n        elif self.cleaned_data[\"action\"] == self.REMOVE:\n            getattr(obj, f\"remove_{self.role}\")(self.cleaned_data[\"user\"])\n\n\nclass EditorsForm(UserGroupForm):\n    role = \"editor\"\n\n\nclass MembersForm(UserGroupForm):\n    role = \"member\"\n\n\nclass UsersForm(UserGroupForm):\n    role = \"user\"\n", "path": "app/grandchallenge/groups/forms.py"}, {"content": "from dal import autocomplete\nfrom django.conf import settings\nfrom django.contrib.auth import get_user_model\nfrom django.contrib.auth.mixins import UserPassesTestMixin\nfrom django.contrib.messages.views import SuccessMessageMixin\nfrom django.db.models import CharField, Q, Value\nfrom django.db.models.functions import Concat\nfrom django.utils.html import format_html\nfrom django.views.generic import FormView\nfrom guardian.mixins import (\n    LoginRequiredMixin,\n    PermissionRequiredMixin as ObjectPermissionRequiredMixin,\n)\nfrom guardian.shortcuts import get_objects_for_user\n\nfrom grandchallenge.verifications.models import Verification\n\n\nclass UserGroupUpdateMixin(\n    LoginRequiredMixin,\n    ObjectPermissionRequiredMixin,\n    SuccessMessageMixin,\n    FormView,\n):\n    raise_exception = True\n\n    def get_permission_object(self):\n        return self.obj\n\n    @property\n    def obj(self):\n        raise NotImplementedError\n\n    def get_context_data(self, **kwargs):\n        context = super().get_context_data(**kwargs)\n        context.update({\"object\": self.obj, \"role\": self.get_form().role})\n        return context\n\n    def get_success_url(self):\n        return self.obj.get_absolute_url()\n\n    def form_valid(self, form):\n        form.add_or_remove_user(obj=self.obj)\n        return super().form_valid(form)\n\n\nclass UserAutocomplete(\n    LoginRequiredMixin, UserPassesTestMixin, autocomplete.Select2QuerySetView\n):\n    def test_func(self):\n        allowed_perms = [\n            \"algorithms.change_algorithm\",\n            \"organizations.change_organization\",\n            \"archives.change_archive\",\n            \"reader_studies.change_readerstudy\",\n            \"workstations.change_workstation\",\n            \"algorithms.change_job\",\n        ]\n        # TODO reduce number of queries\n        return any(\n            get_objects_for_user(user=self.request.user, perms=perm,).exists()\n            for perm in allowed_perms\n        )\n\n    def get_queryset(self):\n        qs = (\n            get_user_model()\n            .objects.order_by(\"username\")\n            .exclude(username=settings.ANONYMOUS_USER_NAME)\n            .annotate(\n                full_name=Concat(\n                    \"first_name\",\n                    Value(\" \"),\n                    \"last_name\",\n                    output_field=CharField(),\n                )\n            )\n            .select_related(\"verification\", \"user_profile\")\n        )\n\n        if self.q:\n            qs = qs.filter(\n                Q(username__icontains=self.q)\n                | Q(email__icontains=self.q)\n                | Q(full_name__icontains=self.q)\n                | Q(verification__email__icontains=self.q)\n            )\n\n        return qs\n\n    def get_result_label(self, result):\n\n        try:\n            is_verified = result.verification.is_verified\n        except Verification.DoesNotExist:\n            is_verified = False\n\n        if is_verified:\n            return format_html(\n                '<img src=\"{}\" width =\"20\" height =\"20\" style=\"vertical-align:top\"> '\n                \"&nbsp; <b>{}</b> &nbsp; {} &nbsp;\"\n                '<i class=\"fas fa-user-check text-success\" '\n                'title=\"Verified email address at {}\">',\n                result.user_profile.get_mugshot_url(),\n                result.get_username(),\n                result.get_full_name().title(),\n                result.verification.email.split(\"@\")[1],\n            )\n        else:\n            return format_html(\n                '<img src=\"{}\" width =\"20\" height =\"20\" style=\"vertical-align:top\"> '\n                \"&nbsp; <b>{}</b> &nbsp; {}\",\n                result.user_profile.get_mugshot_url(),\n                result.get_username(),\n                result.get_full_name().title(),\n            )\n", "path": "app/grandchallenge/groups/views.py"}]}