2012-04-03 3 views
0

J'ai une application Django où plusieurs équipes téléchargent du contenu qui sera analysé. L'application conserve une trace de certaines informations communes dans le contenu analysé. Le problème ici est que chaque équipe a un contenu qui doit être analysé par un analyseur différent, car le contenu est dans un format différent (par exemple, certaines équipes ont un contenu XML, d'autres ont du texte, d'autres ont JSON, etc ...). Chacune des équipes a fourni un analyseur (un module python) qui saisit les informations nécessaires qui sont placées dans les modèles Django correspondants après l'analyse.Django: des applications dépendantes du modèle à partir de l'utilisateur

Ma question est la suivante: quelle est la meilleure façon d'architecturer ceci dans Django où chaque équipe peut avoir sa propre configuration d'analyseur? Il peut être purement backend, pas besoin d'un formulaire utilisateur ou quelque chose comme ça. Ma première pensée était que je créerais un modèle Parser avec ForeignKey à chaque équipe comme ceci:

class Parser(models.Model): 
    team = models.ForeignKey('Team') 
    module_path = models.CharField(max_length=..., blank=False) 

et que module_path serait quelque chose comme « parsers.teamA.XMLparser » qui résiderait dans mon code d'application dans cette voie comme ceci:

parsers/ 
    teamA/ 
     __init__.py 
     XMLparser.py 
    teamB/ 

Puis, quand mon application vient pour analyser le contenu téléchargé, j'aurais ceci:

team = Team.objects.get(id=team_id) 
parser = Parser.objects.get(team=team) 

theParser = __import__(parser.module_path) 
theParser.parse(theStuffToBeParsed) 

Quels sont les problèmes Quelqu'un voit-il avec ça? La seule autre option que je peux penser est de créer des applications Django séparées pour chaque analyseur, mais comment puis-je référencer quelle équipe utilise quelle application dans la base de données (même chose que fait ici?)?

Répondre

1

L'approche que vous prenez me semble valable. Gardez à l'esprit que vous exécutez effectivement du code python arbitraire, donc je n'utiliserais jamais quelque chose comme ça sur un site public et je vous assurerais de faire confiance aux équipes qui écrivent leurs parseurs. Vous pouvez rendre cela un peu plus agréable en écrivant un champ personnalisé pour représenter le chemin du module qui supprimera le besoin de gérer l'importation à chaque fois et traitera plutôt l'importation pour vous et retournera la méthode d'analyse (ou peut-être même mieux Objet d'analyseur dans lequel vous pourriez dire aux équipes d'implémenter une interface)

Le meilleur exemple pourrait être de regarder la source pour ImageField de django ou même CharField. Au lieu d'avoir un modèle CharField, vous auriez un "ModuleField": parser = ModuleField(). La valeur stockée de la base de données serait en effet le chemin vers le module (en faire simplement une sous-classe de CharField), mais remplacerait la méthode to_python. Dans votre nouvelle méthode to_python, manipulez l'importation du module et renvoyez un objet python.

Cet objet python pourrait être quelque chose que vous voulez qu'il soit, à partir de votre exemple, vous pouvez return theParser.parse. Cela se traduirait par si vous avez une instance Parser foo vous pouvez the_parser_method = foo.parser

+0

@ John, merci pour le conseil. Je suis curieux de savoir ce que vous voulez dire par le champ personnalisé pour représenter le chemin du module. Comment cela serait-il fait pour gérer l'importation? – Randy

+0

J'ai édité ma réponse pour répondre à votre suivi – John

Questions connexes