class CConfig(models.Model): name = models.CharField(max_length=128) valuetype = models.CharField(max_length=128) def __unicode__(self): return u'%s' % self.name class Meta: db_table = 'config_client' get_latest_by = 'id' ordering = ['name'] class Client(models.Model): login = models.CharField(max_length=64) password = models.CharField(max_length=16) email = models.CharField(max_length=128) # firstname, surname etc. is stored in CConfig, this is designed for i8n purposes def __unicode__(self): return u'%s' % self.login def __getattr__( self, name ): # this method is called when the attribute for this class doesn't exist # access the shop config class! try: __cfg = CConfig.objects.get( name=name ) __attr = self.clientconfig_set.get( config=__cfg ) except: raise AttributeError else: return u'%s' % __attr.value raise AttributeError def setVar( self, name, value ): cfg = CConfig.objects.get( name=name ) try: attr = self.clientconfig_set.get( config=cfg ) except: attr = ClientConfig( config=cfg, client=self ) attr.save() attr.value = value attr.save() def __setattr__( self, name, value ): # this method is called when the attribute for this class doesn't exist # access the shop config class! try: # if not found, find or create __cfg = CConfig.objects.get( name=name ) except: # try to find attribute in normal object dict # setattr( self, name, value ) self.__dict__[ name ] = value # this is old style 2.4 else: self.setVar( name, value ) class ClientConfig(models.Model): client = models.ForeignKey(Client) config = models.ForeignKey(CConfig) value = models.CharField(max_length=128) def __unicode__(self): return u'%s - %s - %s' % ( self.client, self.config, self.value ) class Meta: db_table = 'client_config' get_latest_by = 'id' ordering = ['client'] if __name__ == '__main__': my_client = Client(email='mymail@example.com', login='me', password='me' my_client.save() # save first my_client.longname = 'Beaver' my_client.species = 'Chicken' my_client.save() # the .species and .longname must exist in the CConfig!