prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Improve the way permissionas are managed in admin
  Currently, use has to use a select2 component with a lot of options and this is super boring, tedious and time consuming. Can we use a list of check boxes instead?
  
  </issue>
  <code>
  [start of shuup/admin/modules/permission_groups/views/edit.py]
  1 # -*- coding: utf-8 -*-
  2 # This file is part of Shuup.
  3 #
  4 # Copyright (c) 2012-2018, Shuup Inc. All rights reserved.
  5 #
  6 # This source code is licensed under the OSL-3.0 license found in the
  7 # LICENSE file in the root directory of this source tree.
  8 from __future__ import unicode_literals
  9 
  10 from django import forms
  11 from django.contrib.auth import get_user_model
  12 from django.contrib.auth.models import Group as PermissionGroup
  13 from django.utils.encoding import force_text
  14 from django.utils.translation import ugettext_lazy as _
  15 
  16 from shuup.admin.forms.fields import Select2MultipleField
  17 from shuup.admin.module_registry import get_modules
  18 from shuup.admin.utils.permissions import get_permission_object_from_string
  19 from shuup.admin.utils.views import CreateOrUpdateView
  20 
  21 
  22 class PermissionGroupForm(forms.ModelForm):
  23     class Meta:
  24         model = PermissionGroup
  25         exclude = ("permissions",)
  26 
  27     def __init__(self, *args, **kwargs):
  28         super(PermissionGroupForm, self).__init__(*args, **kwargs)
  29         initial_permissions = self._get_initial_permissions()
  30         self.fields["name"].help_text = _("The permission group name.")
  31         self.fields["modules"] = forms.MultipleChoiceField(
  32             choices=sorted(self._get_module_choices()),
  33             initial=self._get_enabled_modules(initial_permissions),
  34             required=False,
  35             label=_("Module Permissions"),
  36             help_text=_(
  37                 "Select the modules that should be accessible by this permission group. "
  38                 "Modules with the same permissions as selected modules will be added automatically."
  39             )
  40         )
  41         initial_members = self._get_initial_members()
  42         members_field = Select2MultipleField(
  43             model=get_user_model(),
  44             initial=[member.pk for member in initial_members],
  45             required=False,
  46             label=_("Members"),
  47             help_text=_(
  48                 "Set the users that belong to this permission group."
  49             )
  50         )
  51         members_field.widget.choices = [(member.pk, force_text(member)) for member in initial_members]
  52         self.fields["members"] = members_field
  53 
  54     def _get_module_choices(self):
  55         return set((force_text(m.name), force_text(m.name)) for m in get_modules() if m.name != "_Base_")
  56 
  57     def _get_initial_members(self):
  58         if self.instance.pk:
  59             return self.instance.user_set.all()
  60         else:
  61             return []
  62 
  63     def _get_initial_permissions(self):
  64         permissions = set()
  65         if self.instance.pk:
  66             for perm in self.instance.permissions.all():
  67                 name, module, _ = perm.natural_key()
  68                 permissions.add("%s.%s" % (module, name))
  69         return permissions
  70 
  71     def _get_enabled_modules(self, permissions):
  72         if not self.instance.pk:
  73             return []
  74         permissions = set(permissions)
  75         modules = []
  76         for module in get_modules():
  77             # Ignore modules that haven't configured a name
  78             if module.name != "_Base_" and set(module.get_required_permissions()).issubset(permissions):
  79                 modules.append(force_text(module.name))
  80         return modules
  81 
  82     def _get_required_permissions(self, modules):
  83         permissions = set()
  84         for module in [m for m in get_modules() if m.name in modules]:
  85             permissions.update(set(module.get_required_permissions()))
  86         return permissions
  87 
  88     def clean_members(self):
  89         members = self.cleaned_data.get("members", [])
  90 
  91         return get_user_model().objects.filter(pk__in=members).all()
  92 
  93     def clean(self):
  94         cleaned_data = super(PermissionGroupForm, self).clean()
  95 
  96         permissions = set()
  97         modules = cleaned_data.pop("modules", [])
  98         required_permissions = self._get_required_permissions(modules)
  99 
  100         for permission in required_permissions:
  101             permissions.add(get_permission_object_from_string(permission))
  102 
  103         cleaned_data["required_permissions"] = permissions
  104 
  105         return cleaned_data
  106 
  107     def save(self):
  108         obj = super(PermissionGroupForm, self).save()
  109         obj.permissions = set(self.cleaned_data["required_permissions"])
  110         obj.user_set = set(self.cleaned_data["members"])
  111         return obj
  112 
  113 
  114 class PermissionGroupEditView(CreateOrUpdateView):
  115     model = PermissionGroup
  116     form_class = PermissionGroupForm
  117     template_name = "shuup/admin/permission_groups/edit.jinja"
  118     context_object_name = "permission_group"
  119     add_form_errors_as_messages = True
  120
  [end of shuup/admin/modules/permission_groups/views/edit.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/shuup/admin/modules/permission_groups/views/edit.py b/shuup/admin/modules/permission_groups/views/edit.py
  --- a/shuup/admin/modules/permission_groups/views/edit.py
  +++ b/shuup/admin/modules/permission_groups/views/edit.py
  @@ -36,7 +36,8 @@
               help_text=_(
                   "Select the modules that should be accessible by this permission group. "
                   "Modules with the same permissions as selected modules will be added automatically."
  -            )
  +            ),
  +            widget=forms.CheckboxSelectMultiple
           )
           initial_members = self._get_initial_members()
           members_field = Select2MultipleField(
  
verification_info: {"golden_diff": "diff --git a/shuup/admin/modules/permission_groups/views/edit.py b/shuup/admin/modules/permission_groups/views/edit.py\n--- a/shuup/admin/modules/permission_groups/views/edit.py\n+++ b/shuup/admin/modules/permission_groups/views/edit.py\n@@ -36,7 +36,8 @@\n             help_text=_(\n                 \"Select the modules that should be accessible by this permission group. \"\n                 \"Modules with the same permissions as selected modules will be added automatically.\"\n-            )\n+            ),\n+            widget=forms.CheckboxSelectMultiple\n         )\n         initial_members = self._get_initial_members()\n         members_field = Select2MultipleField(\n", "issue": "Improve the way permissionas are managed in admin\nCurrently, use has to use a select2 component with a lot of options and this is super boring, tedious and time consuming. Can we use a list of check boxes instead?\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n# This file is part of Shuup.\n#\n# Copyright (c) 2012-2018, Shuup Inc. All rights reserved.\n#\n# This source code is licensed under the OSL-3.0 license found in the\n# LICENSE file in the root directory of this source tree.\nfrom __future__ import unicode_literals\n\nfrom django import forms\nfrom django.contrib.auth import get_user_model\nfrom django.contrib.auth.models import Group as PermissionGroup\nfrom django.utils.encoding import force_text\nfrom django.utils.translation import ugettext_lazy as _\n\nfrom shuup.admin.forms.fields import Select2MultipleField\nfrom shuup.admin.module_registry import get_modules\nfrom shuup.admin.utils.permissions import get_permission_object_from_string\nfrom shuup.admin.utils.views import CreateOrUpdateView\n\n\nclass PermissionGroupForm(forms.ModelForm):\n    class Meta:\n        model = PermissionGroup\n        exclude = (\"permissions\",)\n\n    def __init__(self, *args, **kwargs):\n        super(PermissionGroupForm, self).__init__(*args, **kwargs)\n        initial_permissions = self._get_initial_permissions()\n        self.fields[\"name\"].help_text = _(\"The permission group name.\")\n        self.fields[\"modules\"] = forms.MultipleChoiceField(\n            choices=sorted(self._get_module_choices()),\n            initial=self._get_enabled_modules(initial_permissions),\n            required=False,\n            label=_(\"Module Permissions\"),\n            help_text=_(\n                \"Select the modules that should be accessible by this permission group. \"\n                \"Modules with the same permissions as selected modules will be added automatically.\"\n            )\n        )\n        initial_members = self._get_initial_members()\n        members_field = Select2MultipleField(\n            model=get_user_model(),\n            initial=[member.pk for member in initial_members],\n            required=False,\n            label=_(\"Members\"),\n            help_text=_(\n                \"Set the users that belong to this permission group.\"\n            )\n        )\n        members_field.widget.choices = [(member.pk, force_text(member)) for member in initial_members]\n        self.fields[\"members\"] = members_field\n\n    def _get_module_choices(self):\n        return set((force_text(m.name), force_text(m.name)) for m in get_modules() if m.name != \"_Base_\")\n\n    def _get_initial_members(self):\n        if self.instance.pk:\n            return self.instance.user_set.all()\n        else:\n            return []\n\n    def _get_initial_permissions(self):\n        permissions = set()\n        if self.instance.pk:\n            for perm in self.instance.permissions.all():\n                name, module, _ = perm.natural_key()\n                permissions.add(\"%s.%s\" % (module, name))\n        return permissions\n\n    def _get_enabled_modules(self, permissions):\n        if not self.instance.pk:\n            return []\n        permissions = set(permissions)\n        modules = []\n        for module in get_modules():\n            # Ignore modules that haven't configured a name\n            if module.name != \"_Base_\" and set(module.get_required_permissions()).issubset(permissions):\n                modules.append(force_text(module.name))\n        return modules\n\n    def _get_required_permissions(self, modules):\n        permissions = set()\n        for module in [m for m in get_modules() if m.name in modules]:\n            permissions.update(set(module.get_required_permissions()))\n        return permissions\n\n    def clean_members(self):\n        members = self.cleaned_data.get(\"members\", [])\n\n        return get_user_model().objects.filter(pk__in=members).all()\n\n    def clean(self):\n        cleaned_data = super(PermissionGroupForm, self).clean()\n\n        permissions = set()\n        modules = cleaned_data.pop(\"modules\", [])\n        required_permissions = self._get_required_permissions(modules)\n\n        for permission in required_permissions:\n            permissions.add(get_permission_object_from_string(permission))\n\n        cleaned_data[\"required_permissions\"] = permissions\n\n        return cleaned_data\n\n    def save(self):\n        obj = super(PermissionGroupForm, self).save()\n        obj.permissions = set(self.cleaned_data[\"required_permissions\"])\n        obj.user_set = set(self.cleaned_data[\"members\"])\n        return obj\n\n\nclass PermissionGroupEditView(CreateOrUpdateView):\n    model = PermissionGroup\n    form_class = PermissionGroupForm\n    template_name = \"shuup/admin/permission_groups/edit.jinja\"\n    context_object_name = \"permission_group\"\n    add_form_errors_as_messages = True\n", "path": "shuup/admin/modules/permission_groups/views/edit.py"}]}