Backend¶
Le backend pour une version (par exemple Magento 1.7) est représenté par une instance de la classe Backend
.
Chaque connecteur va aussi créer un connector.backend
qui permet aux utilisateurs d’inscrire leurs backends. Par exemple le connecteur Magento a un magento.backend
(_inherit
connector.backend_model.connector_backend
). Ce modèle contient un champ version
qui doit avoir la même lists de versions (avec exactement le même nom) que les instances de Backend
.
Exemple avec le connecteur Magento
# in magentoerpconnect/backend.py
magento = backend.Backend('magento')
""" Generic Magento Backend """
magento1700 = backend.Backend(parent=magento, version='1.7')
""" Magento Backend for version 1.7 """
# in magentoerpconnect/magento_model.py
class MagentoBackend(models.Model):
_name = 'magento.backend'
_description = 'Magento Backend'
_inherit = 'connector.backend'
_backend_type = 'magento'
@api.model
def _select_versions(self):
""" Available versions
Can be inherited to add custom versions.
"""
return [('1.7', 'Magento 1.7')]
# <snip>
version = fields.Selection(
selection='_select_versions',
string='Version',
required=True,
)
location = fields.Char(string='Location', required=True)
username = fields.Char(string='Username')
password = fields.Char(string='Password')
# <snip>
Dans le code ci-dessus, “1.7” est la clé de correspondance entre l’instance de Backend
(magento1700
) et l’enregistrement magento_backend
.
-
class
connector.backend.
Backend
(service=None, version=None, parent=None, registry=None)[source]¶ Bases :
object
Un backend représente un système avec lequel interagir, comme Magento, Prestashop, Redmine, …
Il possède trois propriétés :
-
service
¶ Le nom du service, par exemple “magento”
-
version
¶ La version du service. Par exemple “1.7”
-
parent
¶ Un backend parent. Lorsqu’aucune classe
ConnectorUnit
n’est trouvée pour un backend, elle est cherchée dans le parent.
La structure des Backends est la partie clé du framework, mais elle est plutôt simple.
- Une instance de
Backend
contient un registre de classesConnectorUnit
- Il peut renvoyer la classe
ConnectorUnit
à utiliser pour une tâche - Si aucune
ConnectorUnit
n’est inscrite pour une tâche, le parent direct est interrogé (et ainsi de suite)
Les Backends ont deux mécanismes différents d’extension. L’un est plus vertical (entre plusieurs versions) et l’autre est plus horizontal car il permet de modifier le comportement pour une version donnée du backend.
Pour l’exemple, disons que nous avons les versions suivantes de backend
<Magento> | ----------------- | | <Magento 1.7> <Magento 2.0> | <Magento with specific>
Et voici la façon dont elles sont déclarées en Python
magento = Backend('magento') magento1700 = Backend(parent=magento, version='1.7') magento2000 = Backend(parent=magento, version='2.0') magento_specific = Backend(parent=magento1700, version='1.7-specific')
Dans le graphe ci-dessus,
<Magento>
va contenir toutes les classes partagées entre toutes les versions. Chaque version de Magento (<Magento 1.7>
,<Magento 2.0>
) va utiliser les classes définies sur<Magento>
, sauf si elles ont inscrit leur propres classes. C’est la même chose pour<Magento avec specifique>
mais celui-ci contient des personnalisations qui sont spécifiques à une instance (typiquement pour mettre en place des mappeurs spécifiques à une instance).Voici comment inscrire des classes sur
<Magento>
et une autre sur<Magento 1.7>
@magento class Synchronizer(ConnectorUnit): _model_name = 'res.partner' @magento class Mapper(ConnectorUnit): _model_name = 'res.partner' @magento1700 class Synchronizer1700(Synchronizer): _model_name = 'res.partner'
Ici, la méthode
get_class()
appelé surmagento1700
renverraitmagento1700.get_class(Synchronizer, session, 'res.partner') # => Synchronizer1700 magento1700.get_class(Mapper, session, 'res.partner') # => Mapper
C’est le mécanisme d’extension verticale, il dit que chaque version fille est capable d’étendre ou remplacer le comportement de son parent.
Note
when using the framework, you won’t need to call
get_class()
, usually, you will callconnector.connector.ConnectorEnvironment.get_connector_unit()
.L’extension verticale est celle que vous utiliserez probablement le plus, parce que la plupart des choses que vous modifierez concerne vos applications personnalisées ou des comportements différents selon les versions du backend.
Cependant il peut arriver que nous ayons besoin de changer le comportement d’un connecteur, en installant un module. Par exemple, imaginons que nous ayons déjà un
ImportMapper
pour les articles dans le Connecteur Magento. Nous créons un module (générique) pour gérer le catalogue d’une manière plus avancée. Nous redéfinissons unAdvancedImportMapper
qui devrait être utilisé quand le module est installé. Ceci est le mécanisme d’extension horizontal.Remplace une clase
ConnectorUnit
par une autre dans le backend@backend(replacing=ImportMapper) class AdvancedImportMapper(ImportMapper): _model_name = 'product.product'
Avertissement
L’extension horizontale devrait être utilisée de manière très occasionnelle et précautionneuse, car dès que deux modules voudront remplacer la même classe il y aura un conflit (qui nécessiterait de créer un troisième module pour lier les deux, le remplacement pouvant prendre un tuple de classes à remplacer et ceci étant exponentiel). Ce mécanisme ne devrait être utilisé que dans certains circonstances bien précises pour des modules génériques.
-
get_class
(base_class, session, model_name)[source]¶ Trouve une sous-classe correspondante à
base_class
dans les classes inscrites.Paramètres: - base_class (
connector.connector.MetaConnectorUnit
) – Classe (et sous-classe) à rechercher dans le registre - session (
connector.session.ConnectorSession
) – session en cours
- base_class (
-
register_class
(cls, replacing=None)[source]¶ Inscrit une classe dans le backend
Paramètres: - cls (
connector.connector.MetaConnectorUnit
) – la classe ConnectorUnit à inscrire - replacing (
connector.connector.MetaConnectorUnit
) – optionnel, la classe ConnectorUnit à remplacer
- cls (
-
service
-