Browse Source

Minor fixes
Update implementation notes

Fabs 10 years ago
parent
commit
a7a5f9929e
4 changed files with 46 additions and 59 deletions
  1. 5 7
      coin/configuration/admin.py
  2. 26 3
      coin/configuration/models.py
  3. 14 44
      coin/offers/models.py
  4. 1 5
      coin/vpn/models.py

+ 5 - 7
coin/configuration/admin.py

@@ -6,9 +6,13 @@ from polymorphic.admin import PolymorphicParentModelAdmin, PolymorphicChildModel
 class ConfigurationAdmin(PolymorphicParentModelAdmin):
 class ConfigurationAdmin(PolymorphicParentModelAdmin):
     base_model = Configuration
     base_model = Configuration
     polymorphic_list = True
     polymorphic_list = True
-    list_display = ('model_name','configuration_type_name', 'offersubscription')
+    list_display = ('model_name','configuration_type_name', 'offersubscription', 'offer_subscription_member')
     search_fields = ['polymorphic_ctype']
     search_fields = ['polymorphic_ctype']
 
 
+    def offer_subscription_member(self, config):
+        return config.offersubscription.member
+    offer_subscription_member.short_description = 'Membre'
+
     def get_child_models(self):
     def get_child_models(self):
         """
         """
         Renvoi la liste des modèles enfants de Configuration
         Renvoi la liste des modèles enfants de Configuration
@@ -17,10 +21,4 @@ class ConfigurationAdmin(PolymorphicParentModelAdmin):
         """
         """
         return (tuple((x.base_model, x) for x in PolymorphicChildModelAdmin.__subclasses__()))
         return (tuple((x.base_model, x) for x in PolymorphicChildModelAdmin.__subclasses__()))
 
 
-
-
-    # def offer_subscription_subscritption_date(self, config):
-    #     return config.offersubscription.subscription_date
-    # offer_subscription_subscritption_date.short_description = 'Date'
-
 admin.site.register(Configuration, ConfigurationAdmin)
 admin.site.register(Configuration, ConfigurationAdmin)

+ 26 - 3
coin/configuration/models.py

@@ -3,33 +3,56 @@ from django.db import models
 from polymorphic import PolymorphicModel
 from polymorphic import PolymorphicModel
 from coin.offers.models import OfferSubscription
 from coin.offers.models import OfferSubscription
 
 
+"""
+Implementation note : Configuration is a PolymorphicModel.
+The childs of Configuration are the differents models to store
+technical informations of a subscibtion.
+
+To add a new configuration backend, you have to create a new app with a model
+which inherit from Configuration.
+Your model can implement Meta verbose_name to have human readable name and a 
+url_namespace variable to specify the url namespace used by this model.
+"""
+
 class Configuration(PolymorphicModel):
 class Configuration(PolymorphicModel):
 
 
     offersubscription = models.OneToOneField(OfferSubscription, blank=True, 
     offersubscription = models.OneToOneField(OfferSubscription, blank=True, 
                                              null=True,
                                              null=True,
-                                             related_name='configuration')
+                                             related_name='configuration',
+                                             verbose_name='Abonnement')
 
 
     @staticmethod
     @staticmethod
     def get_configurations_choices_list():
     def get_configurations_choices_list():
         """
         """
-        Génère automatiquement la liste de choix possibles en fonction
-        des classes enfants de Configuration
+        Génère automatiquement la liste de choix possibles de configurations
+        en fonction des classes enfants de Configuration
         """
         """
         return tuple((x().__class__.__name__,x()._meta.verbose_name) 
         return tuple((x().__class__.__name__,x()._meta.verbose_name) 
             for x in Configuration.__subclasses__())
             for x in Configuration.__subclasses__())
     
     
     def model_name(self):
     def model_name(self):
         return self.__class__.__name__
         return self.__class__.__name__
+    model_name.short_description = 'Nom du modèle'
 
 
     def configuration_type_name(self):
     def configuration_type_name(self):
         return self._meta.verbose_name
         return self._meta.verbose_name
+    configuration_type_name.short_description = 'Type'
 
 
     def get_absolute_url(self):
     def get_absolute_url(self):
+        """
+        Renvoi l'URL d'accès à la page "details" de l'objet
+        Une url doit être nommée "details"
+        """
         from django.core.urlresolvers import reverse
         from django.core.urlresolvers import reverse
         return reverse('%s:details' % self.get_url_namespace(), 
         return reverse('%s:details' % self.get_url_namespace(), 
                        args=[str(self.id)])
                        args=[str(self.id)])
 
 
     def get_url_namespace(self):
     def get_url_namespace(self):
+        """
+        Renvoi le namespace utilisé par la configuration. Utilise en priorité
+        celui définit dans la classe enfant dans url_namespace sinon
+        par défaut utilise le nom de la classe en minuscule
+        """
         if self.url_namespace:
         if self.url_namespace:
             return self.url_namespace
             return self.url_namespace
         else:
         else:

+ 14 - 44
coin/offers/models.py

@@ -11,30 +11,19 @@ from coin.resources.models import IPSubnet
 class Offer(models.Model):
 class Offer(models.Model):
     """Description of an offer available to subscribers.
     """Description of an offer available to subscribers.
 
 
-    Implementation notes: achieving genericity is difficult, especially
-    because different technologies may have very different configuration
-    parameters.
-
-    Technology-specific configuration (e.g. for VPN) is implemented as a
-    model having a OneToOne relation to OfferSubscription.  In order to
-    reach the technology-specific configuration model from an
-    OfferSubscription, the OneToOne relation MUST have a related_name
-    equal to one of the backends in OFFER_BACKEND_CHOICES (for instance
-    "openvpn_ldap").
-
+    Implementation notes:
+    configuration_type store the model name of the configuration backend
+    (ex VPNConfiguration).
+    The choices list is dynamically generated at start in the __init__
     """
     """
-    # OFFER_BACKEND_CHOICES = (
-    #     ('openvpn_ldap', 'OpenVPN (LDAP)'),
-    #     # Use this if you don't actually want to implement a backend, for
-    #     # instance if you resell somebody else's offers and don't manage
-    #     # technical information yourself.
-    #     ('none', 'None'),
-    # )
+
     def __init__(self, *args, **kwargs):
     def __init__(self, *args, **kwargs):
         from coin.configuration.models import Configuration
         from coin.configuration.models import Configuration
         super(Offer, self).__init__(*args, **kwargs)
         super(Offer, self).__init__(*args, **kwargs)
-        """Génère automatiquement la liste de choix possibles de types
-        de configurations en fonction des classes enfants de Configuration"""
+        """
+        Génère automatiquement la liste de choix possibles de types
+        de configurations en fonction des classes enfants de Configuration
+        """
         self._meta.get_field_by_name('configuration_type')[0]._choices = (
         self._meta.get_field_by_name('configuration_type')[0]._choices = (
             Configuration.get_configurations_choices_list())
             Configuration.get_configurations_choices_list())
 
 
@@ -56,9 +45,6 @@ class Offer(models.Model):
                                       blank=False, null=False,
                                       blank=False, null=False,
                                       verbose_name='Frais de mise en service',
                                       verbose_name='Frais de mise en service',
                                       help_text='en €')
                                       help_text='en €')
-    # TODO: really ensure that this field does not change (as it would
-    # seriously break subscriptions)
-    # backend = models.CharField(max_length=50, choices=OFFER_BACKEND_CHOICES)
 
 
     def get_configuration_type_display(self):
     def get_configuration_type_display(self):
         """
         """
@@ -84,13 +70,9 @@ class OfferSubscription(models.Model):
     """Only contains administrative details about a subscription, not
     """Only contains administrative details about a subscription, not
     technical.  Nothing here should end up into the LDAP backend.
     technical.  Nothing here should end up into the LDAP backend.
 
 
-    Implementation notes: the model actually implementing the backend
-    (technical configuration for the technology) MUST relate to this class
-    with a OneToOneField whose related name is a member of
-    OFFER_BACKEND_CHOICES, for instance:
-
-      models.OneToOneField('offers.OfferSubscription', related_name="openvpn_ldap")
-
+    Implementation notes: the Configuration model (which actually implementing the backend
+    (technical configuration for the technology)) relate to this class
+    with a OneToOneField
     """
     """
     subscription_date = models.DateField(
     subscription_date = models.DateField(
         null=False,
         null=False,
@@ -111,21 +93,9 @@ class OfferSubscription(models.Model):
     member = models.ForeignKey('members.Member', verbose_name='Membre')
     member = models.ForeignKey('members.Member', verbose_name='Membre')
     offer = models.ForeignKey('Offer', verbose_name='Offre')
     offer = models.ForeignKey('Offer', verbose_name='Offre')
 
 
-    # @property
-    # def configuration(self):
-    #     """Returns the configuration object associated to this subscription,
-    #     according to the backend type specified in the offer.  Yes, this
-    #     is hand-made genericity.  If you can think of a better way, feel
-    #     free to propose something.
-    #     """
-    #     if self.offer.backend == 'none' or not hasattr(self, self.offer.backend):
-    #         return
-    #     return getattr(self, self.offer.backend)
-
     def __unicode__(self):
     def __unicode__(self):
-        return u'%s - %s - %s - %s' % (self.member, self.offer.name,
-                                       self.subscription_date,
-                                       self.offer.configuration_type)
+        return u'%s - %s - %s' % (self.member, self.offer.name,
+                                       self.subscription_date)
 
 
     class Meta:
     class Meta:
         verbose_name = 'abonnement'
         verbose_name = 'abonnement'

+ 1 - 5
coin/vpn/models.py

@@ -15,11 +15,7 @@ from coin import validation
 
 
 class VPNConfiguration(CoinLdapSyncMixin, Configuration):
 class VPNConfiguration(CoinLdapSyncMixin, Configuration):
     url_namespace = "vpn"
     url_namespace = "vpn"
-    # backend_name = "openvpn_ldap"
-    # administrative_subscription = models.OneToOneField(
-    #     'offers.OfferSubscription',
-    #     related_name=backend_name,
-    #     validators=[ValidateBackendType(backend_name)])
+
     activated = models.BooleanField(default=False)
     activated = models.BooleanField(default=False)
     login = models.CharField(max_length=50, unique=True, blank=True,
     login = models.CharField(max_length=50, unique=True, blank=True,
                              help_text="leave empty for automatic generation")
                              help_text="leave empty for automatic generation")