Supposons le cas suivant :
J’ai des pages et des catégories. Une page peut avoir une catégorie.
Nous avons donc les modèles suivants :
class Category(models.Model):
  name = models.CharField(max_length=200)
  slug = models.SlugField(max_length=200,unique=True)
class Page(models.Model):
  title = models.CharField(_('title'), max_length=200)
  content = models.TextField(_('content'))
  category = models.ForeignKey(Category, related_name = 'cat')

Maintenant supposons que à cela, nous désirions ajouter, pour une catégorie, une page principale.
Dans mon cas, cela me permet, si j’ai une page principale, d’afficher le contenu de celle-ci lorsque l’on charge la page de la catégorie.
Mais après, à vous de voir ce que vous désirez faire :)

Dans notre modèle de catégorie, nous allons donc ajouter une relation vers le modèle Page. Logique !
Cependant, page = models.ForeignKey(Page,blank=True,null=True)
Ne fonctionnera pas. En effet la classe Page n’est pas encore définie lorsque vous définissez la classe Category.

La solution est cependant très simple. Il suffit de ne pas faire un appel direct à la classe Page. Mais de mentionner son nom dans une chaine de caractères :
page = models.ForeignKey('Page', blank=True,null=True)

Ainsi vous ne faites pas d’appel à la classe Page lors de l’instanciation de Category. Et lorsque Django initialize vos modèles et qu’il cherche la classe Page, celle-ci a déjà été déclarée.
Vous avez défini votre relation entre modèles à deux sens.

Ruby est très développé et très bien document lorsqu’il s’agit de développer des applications web.
Mais parce qu’il n’y a pas que le web dans la vie (ah bon ???), il peut être utile, même dans le cas du développement web, de mettre en place des applications console.

Par console, j’entends sans aucune interface graphique. Celles-ci sont encore un autre sujet.

Du coup en faisant quelques recherches, j’ai découvert SimpleConsole, qui est justement un framework de développement d’applications console simples.
Et en plus il gère un (semblant) de MVC.

Votre application va donc se diviser en deux parties.
Supposons un fichier « myapp.rb », avec le code suivant :
#!/usr/bin/env ruby -w
require 'rubygems'
require 'simpleconsole'
require 'views/myapp'

class Controller < SimpleConsole::Controller
  params :string => {:n => :name, :w => :word}

  def default
    @name = params[:name]
    @word = params[:word]
  end
end

SimpleConsole::Application.run(ARGV, Controller, View)

Puis un fichier views/myapp.rb
class View < SimpleConsole::View
  def default
    puts "Your name is " + @name + "."
    puts "You wanted me to say the word " + @word + "."
  end
end

Si vous exécutez
ruby myapp.rb -name Damien -w Yay

La console vous retournera alors :

Your name is Damien.
You wanted me to say the word Yay.

Le code est tout d'abord interprété par le contrôleur pour ensuite être transmis à la vue, qui renvoie le contenu que vous désirez.
C'est du pseudo MVC et la chose serait largement améliorable.

Mais c'est un bon début pour une application console qui se doit d'être simple.
Et puis vu que l'application ne semble plus maintenue, il est possible que je la forke et que je fasse quelques commits dessus ;)

J’aime beaucoup le dessin permettant d’expliquer (globalement) la méthode de codage MVC de CakePHP dans OCPHP (page 3).

Prenons un exemple. Dans RefStats, je génère des graphiques en me basant sur des données d’une base de données dont le modèle est le suivant :

myBase

  • idSite (primary key)
  • idKeyword (primary key)
  • date (primary key)
  • position

J’aurais pu, dans mon controlleur, faire une requête de sélection. On ne peut plus simple !
!

$this->myBase->findAll(array(‘idSite’ => $site, ‘idKeyword’ => $keyword));

Seulement voila, les données retournées par cette requête sont dans un format inexploitable par ma vue par la suite (dans le but d’un affichage dans un format quelconque (html, xml ou csv par exemple).

J’ai donc créé une méthode dans mon modèle qui execute la même requête de findAll et qui traite les données retournées dans le but de retourner un tableau exploitable par la suite.

La solution de facilité aurait été de faire le findAll dans le controlleur tout de même et de traiter les données là-bas.

Et pourtant, quand on y réflechit, ce n’est absolument pas le plus simple. En effet, cela va quand vous n’avez besoin de récupérer les données qu’une seule fois dans votre application.

Mais là, je dois les récupérer au moins 3 fois à trois endroits différents.

Vive les répétitions de code dans le controlleur ! Et les multiplications de risques de bugs.

Le mentra qui se trouve en dessous de l’image que j’ai donné ci-dessus dans le document pdf est donc on ne peut plus à prendre au sérieux. « Think twice, code once ». « Réflechissez deux fois, ne codez qu’une ».

Si vous ne comprenez pas bien comment MVC fonctionne et que vous désirez approfondir cela, n’hésitez pas à assister à la conférence zend framework qui se déroule dans un mois et dans laquelle je ferais une présentation complète de la méthode. Les inscriptions sont ouvertes, on a encore largement assez de place et c’est gratuit !

 
Fork me on GitHub