0

我有一个 Django 应用程序,多个团队上传将被解析的内容。该应用程序会跟踪解析内容中的某些常见信息。这里的问题是每个团队都有内容需要由不同的解析器解析,因为内容的格式不同(例如,有些团队有 XML 内容,有些有文本,有些有 JSON,等等)。每个团队都提供了一个解析器(一个 python 模块),它在解析后获取必要的信息,这些信息被放入相应的 Django 模型中。

我的问题是:在 Django 中构建它的最佳方法是什么,每个团队都可以正确设置自己的解析器?它可以是纯粹的后端,不需要用户表单或类似的东西。我的第一个想法是,我会Parser为每个团队创建一个带有 ForeignKey 的模型,如下所示:

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

module_path将类似于“parsers.teamA.XMLparser”,它将驻留在该路径中的我的应用程序代码中,如下所示:

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

然后当我的应用程序来解析上传的内容时,我会这样:

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

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

有人认为这有什么问题?我能想到的唯一其他选择是为每个解析器创建单独的 Django 应用程序,但是我将如何引用哪个团队使用数据库中的哪个应用程序(与此处所做的相同?)?

4

1 回答 1

1

你采取的方法对我来说似乎有效。请记住,您正在有效地运行任意 python 代码,所以我永远不会在面向公众的网站上使用这样的东西,并确保您信任编写解析器的团队。

您可能会通过编写一个自定义字段来表示模块路径来使这更好一点,这将消除每次处理导入的需要,而是为您处理导入并返回解析方法(或者甚至更好的 Parser 对象,您可以告诉团队实现一个接口)

最好的例子可能是查看 django 的 ImageField 甚至 CharField 的源代码。而不是让你的模型有一个 CharField,你会有一个 "ModuleField": parser = ModuleField()。数据库存储的值确实是模块的路径(因此只需使其成为 CharField 的子类),但会覆盖 to_python 方法。在您的新 to_python 方法中处理导入模块并返回一个 python 对象。

该 python 对象可以是您想要的任何东西,从您的示例中您可以return theParser.parse。这将导致如果您有一个 Parser 实例foo,您可以the_parser_method = foo.parser

于 2012-04-03T18:30:52.787 回答