Django: зависимые от модели приложения на выбор в зависимости от пользователя - PullRequest
0 голосов
/ 03 апреля 2012

У меня есть приложение 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 для каждого парсера, но как мне указать, какая команда использует какое приложение в базе данных (как здесь?)

1 Ответ

1 голос
/ 03 апреля 2012

Подход, который вы принимаете, мне кажется действительным.Имейте в виду, что вы эффективно запускаете произвольный код Python, поэтому я бы никогда не использовал что-то подобное на общедоступном сайте и обеспечил бы доверие групп, пишущих свои парсеры.

Вы можете сделать это немного лучше, написавнастраиваемое поле для представления пути к модулю, которое устраняет необходимость каждый раз обрабатывать импорт и вместо этого будет обрабатывать импорт для вас и возвращать метод синтаксического анализа (или, может быть, даже лучше объект Parser, где вы можете указать командам реализовать интерфейс)

Лучшим примером может быть поиск источника для ImageField или даже CharField от django.Вместо того, чтобы ваша модель имела CharField, у вас будет «ModuleField»: parser = ModuleField().Сохраненное значение базы данных действительно будет путем к модулю (поэтому просто сделайте его подклассом CharField), но переопределите метод to_python.В вашем новом методе to_python обработайте импорт модуля и верните объект python.

Этот объект python может быть тем, чем вы хотите, из вашего примера вы можете return theParser.parse.Это приведет к тому, что если у вас есть экземпляр Parser foo, вы могли бы the_parser_method = foo.parser

...