Crème CRM
[Creme 1.5] Gros changement pour SettinKey/SettingValue - Version imprimable

+- Crème CRM (https://www.cremecrm.com/forum)
+-- Forum : Développeurs (https://www.cremecrm.com/forum/forumdisplay.php?fid=10)
+--- Forum : Général (https://www.cremecrm.com/forum/forumdisplay.php?fid=11)
+--- Sujet : [Creme 1.5] Gros changement pour SettinKey/SettingValue (/showthread.php?tid=65)



[Creme 1.5] Gros changement pour SettinKey/SettingValue - genglert - 02-09-2014

Attention ! les explications suivantes concernent uniquement les développeurs d'application ; les changements sont transparents pour les simples utilisateurs.

Les SettinKey/SettingValue permettent la mise en place de variables qui définissent le comportement de l'application, et qui sont accessibles depuis l'interface utilisateur (au contraire du fichier settings.py - ou plutôt local_settings.py - uniquement accessible pour l'administrateur). elles permettent par exemple de régler l'heure d'envoi des e-mails de rappel pour les ToDos (pour cela allez dans la configuration générale -> portail des assistants).

La version 1.5 s'accompagne d'un gros changement d'implémentation des SettinKey/SettingValue, motivé par les raisons suivantes:
  • La description des clés (SettinKey) était stockée en base, et donc la langue des descriptions était figée à la langue de l'installation.
  • En fait, que les clés soient stockées en base étaient tout bonnement inutile, puisque les utilisateurs ne peuvent pas en créer de nouvelles ; seules les valeurs (SettingValue) ont besoin d'être en base.
  • Les modèles SettinKey/SettingValue étaient dans creme_config ; or cette app se veut être une simple interface de configuration ; de plus creme_core utilisait lui-même des SettinKey/SettingValue dans son code, ce qui induisait une dépendance réciproque peu élégante (même si pas gênante en pratique)

Puisque régler ces différents problèmes allait provoquer des incompatibilités, il a été décidé de les régler tous d'un seul coup, plutôt que d'avoir des changements cassant la compatibilité étalés sur 2 ou 3 versions ; la décision a été facilitée par l'utilisation a priori assez rare de cette fonctionnalité.

Nouvelle architecture :
  • Les SettingKey ne sont plus des modèles ; ce sont de simples instances d'objets Python (c'est à dire non sauvegardées en base), enregistrées dans une registry.
  • Le champ 'key' des SettingValue a été remplacé par un champ 'key_id'.
  • De plus ils sont maintenant dans creme_core (l'un dans "models", l'autre dans "core.setting_key" .

Voici un petit guide expliquant comment modifier votre code utilisant les SettinKey/SettingValue, pour passer de Creme1.4 à Creme1.5.

Remarque : notez bien que vous n'avez pas à vous soucier de la migration de la base de données ; celle-ci qui est effectuée par la commande 'migrate' comme d'habitude, et se charge de vos SettinKey/SettingValue aussi bien que celles fournies par Creme. Vous n'avez à vous soucier que de modifier votre code (ce qui est déjà pas mal !).

Avant vous construisiez vos SettingKey dans le populate.py de votre app ; quelque chose du genre:

Code :
[...]
from creme.creme_config.models import SettingKey, SettingValue
[...]
from .constants import MY_KEY_ID
[...]

class Populator(BasePopulator):
        [...]
        sk = SettingKey.create(pk=MY_KEY_ID,
                               description=_('Description of my key'),
                               app_label='my_app', type=SettingKey.INT,
                              )
        SettingValue.create_if_needed(key=sk, user=None, value=42)
       [...]

Créez un fichier setting_keys.py à la racine de votre app, dans lequel vous déplacez la création du SettingKey, avec quelques modifications (détaillées après) :

Code :
# -*- coding: utf-8 -*-

from django.utils.translation import ugettext_lazy as _

from creme.creme_core.core.setting_key import SettingKey

from .constants import MY_KEY_ID


my_skey = SettingKey(id=MY_KEY_ID,
                     description=_('Description of my key'),
                     app_label='my_app', type=SettingKey.INT,
                    )

Notez les différences:
  • SettingKey n'est plus importé de creme_config.models, mais de creme.creme_core.core.setting_key
  • La méthode statique SettingKey.create() a disparue ; on instancie notre objet simplement, que l'on stocke dans une variable globale.
  • On utilise un ugettext_lazy() et non plus un ugettext() pour la description.

Vous pouvez ensuite revenir modifier votre populate.py:

Code :
[...]
from creme.creme_core.models import SettingValue #SettingKey a disparu + import depuis creme_core et plus depuis creme_config
[...]
from .setting_keys import my_skey #import de votre instance, et non plus de l'ID
[...]

class Populator(BasePopulator):
        [...]
        SettingValue.create_if_needed(key=my_skey, user=None, value=42) #Notez le paramètre  'key' qui a changé
        [...]

Vous devez ensuite modifier votre creme_core_register.py pour enregistrer votre SettingKey ; rajoutez ces quelques lignes :

Code :
from creme.creme_core.core.setting_key import setting_key_registry

from .setting_keys import my_skey

setting_key_registry.register(my_skey)

Il reste à modifier le code qui utilise une SettingValue:
  • Changez l'import a depuis creme_config.models pour creme_core.models.
  • Vos requêtes doivent éventuellement être légèrement modifiées pour prendre en compte le champ 'key' (ForeignKey vers SettingKey) devenu 'key_id' (Charfield).

Par exemple :
Code :
[...]
from creme.creme_config.models import SettingValue
[...]
    my_val = SettingValue.objects.get(key=MY_KEY_ID).value
[...]
deviendrait:
Code :
[...]
from creme.creme_core.models import SettingValue
[...]
    my_val = SettingValue.objects.get(key_id=MY_KEY_ID).value
[...]