From 782898bc75e99308044ff5029374e092b80a1975 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= <fpeters@entrouvert.com>
Date: Tue, 19 May 2020 20:30:12 +0200
Subject: [PATCH] general: add connector class method to get new/edit form
 class (#43128)

---
 passerelle/apps/pastell/__init__.py |  3 ---
 passerelle/apps/pastell/models.py   |  5 +++++
 passerelle/base/models.py           | 20 ++++++++++++++++++++
 passerelle/views.py                 | 16 +---------------
 4 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/passerelle/apps/pastell/__init__.py b/passerelle/apps/pastell/__init__.py
index 03c880db..42526333 100644
--- a/passerelle/apps/pastell/__init__.py
+++ b/passerelle/apps/pastell/__init__.py
@@ -27,8 +27,5 @@ class AppConfig(django.apps.AppConfig):
         from . import models
         return models.Pastell
 
-    def get_form_class(self):
-        from . import forms
-        return forms.PastellForm
 
 default_app_config = 'passerelle.apps.pastell.AppConfig'
diff --git a/passerelle/apps/pastell/models.py b/passerelle/apps/pastell/models.py
index a7c8bad1..d49ddf3f 100644
--- a/passerelle/apps/pastell/models.py
+++ b/passerelle/apps/pastell/models.py
@@ -44,6 +44,11 @@ class Pastell(BaseResource):
     def get_verbose_name(cls):
         return cls._meta.verbose_name
 
+    @classmethod
+    def get_manager_form_class(cls):
+        from .forms import PastellForm
+        return PastellForm
+
     def pastell_request(self, endpoint, **kwargs):
         if self.keystore:
             kwargs['cert'] = (self.keystore.path, self.keystore.path)
diff --git a/passerelle/base/models.py b/passerelle/base/models.py
index cdf322ff..f7b7c44e 100644
--- a/passerelle/base/models.py
+++ b/passerelle/base/models.py
@@ -18,6 +18,8 @@ from django.core.exceptions import ValidationError, ObjectDoesNotExist, Permissi
 from django.core.urlresolvers import reverse
 from django.db import connection, models, transaction
 from django.db.models import Q
+from django.forms.models import modelform_factory
+from django.forms.widgets import ClearableFileInput
 from django.test import override_settings
 from django.utils.text import slugify
 from django.utils import timezone, six
@@ -36,6 +38,7 @@ from model_utils.managers import InheritanceManager as ModelUtilsInheritanceMana
 import passerelle
 import requests
 from passerelle.compat import json_loads
+from passerelle.forms import GenericConnectorForm
 from passerelle.utils.api import endpoint
 from passerelle.utils.jsonresponse import APIError
 
@@ -128,6 +131,7 @@ class BaseResource(models.Model):
 
     parameters = None
     manager_view_template_name = None
+    manager_form_base_class = GenericConnectorForm
 
     # permission descriptions
     _can_access_description = _('Access is limited to the following API users:')
@@ -159,6 +163,22 @@ class BaseResource(models.Model):
     def is_enabled(cls):
         return getattr(settings, 'PASSERELLE_APP_%s_ENABLED' % cls._meta.app_label.upper(), True)
 
+    @classmethod
+    def get_manager_form_class(cls, **kwargs):
+        '''
+        Return the class to use for new/edit connector forms.
+        '''
+        form_class = modelform_factory(
+            cls,
+            form=cls.manager_form_base_class,
+            **kwargs)
+        for field in form_class.base_fields.values():
+            if isinstance(field.widget, ClearableFileInput):
+                field.widget.template_with_initial = ''\
+                        '%(initial_text)s: %(initial)s '\
+                        '%(clear_template)s<br />%(input_text)s: %(input)s'
+        return form_class
+
     @property
     def requests(self):
         if getattr(self, '_requests', None) is None:
diff --git a/passerelle/views.py b/passerelle/views.py
index 4adb71af..54e030b1 100644
--- a/passerelle/views.py
+++ b/passerelle/views.py
@@ -41,8 +41,6 @@ from django.core.urlresolvers import reverse
 from django.utils.timezone import make_aware
 from django.utils.translation import ugettext_lazy as _
 from django.utils.encoding import force_bytes, force_text
-from django.forms.models import modelform_factory
-from django.forms.widgets import ClearableFileInput
 from django.utils.six.moves.urllib.parse import quote
 
 from dateutil import parser as date_parser
@@ -54,7 +52,6 @@ from passerelle.utils.jsonresponse import APIError
 from passerelle.utils.json import unflatten
 
 from .utils import to_json, is_authorized
-from .forms import GenericConnectorForm
 from .forms import ResourceLogSearchForm
 
 if 'mellon' in settings.INSTALLED_APPS:
@@ -156,18 +153,7 @@ class GenericConnectorMixin(object):
             raise Http404()
 
         self.model = app.get_connector_model()
-        if hasattr(app, 'get_form_class'):
-            self.form_class = app.get_form_class()
-        else:
-            self.form_class = modelform_factory(
-                self.model,
-                form=GenericConnectorForm,
-                exclude=self.exclude_fields)
-            for field in self.form_class.base_fields.values():
-                if isinstance(field.widget, ClearableFileInput):
-                    field.widget.template_with_initial = ''\
-                        '%(initial_text)s: %(initial)s '\
-                        '%(clear_template)s<br />%(input_text)s: %(input)s'
+        self.form_class = self.model.get_manager_form_class(exclude=self.exclude_fields)
 
     def dispatch(self, request, *args, **kwargs):
         self.init_stuff(request, *args, **kwargs)
-- 
2.27.0.rc0

