Джанго: Как я могу позволить пользователю определять семантические отношения между объектами? - PullRequest
3 голосов
/ 08 июля 2011

В MediaWiki пользователь может перейти по ссылке на страницу, просто введя [[Имя страницы]]. В семантических медиа-вики пользователь может создать семантическое отношение к странице, указав [[example :: Some Page]] в качестве примера страницы.

Я хочу быть в состоянии сделать это с моделями Django.

Например, я хочу, чтобы пользователь мог написать описание для объекта «Задача» в приложении рабочего процесса и добавить что-то вроде:

Мне бы тоже хотелось иметь возможность делать семантические вещи.

Наконец, я бы хотел посмотреть на пользователя 43 и посмотреть, какие модели ссылаются на него.

Есть ли пакет django, который сделает это частично или полностью? Если нет, то как обычно называется эта методология?

1 Ответ

1 голос
/ 09 июля 2011

Прежде всего, я бы настроил следующее для обработки обнаружения и создания ссылки:

  1. Создайте ModelForm для получения отправленного пользователем Task.Создайте пользовательский валидатор для работы с полем description этой формы.Этот валидатор проверит, что любые ссылки, введенные пользователем, соответствуют указанному вами формату [[:]].
  2. Переопределить метод сохранения на модели Task.Это хорошее время, чтобы проверить содержание описания и создать соответствующие ссылки.
    • Примечание: я бы обернул функцию представления, обрабатывающую этот запрос, в @transaction.commit_on_success декоратор , чтобы либо была создана модель и все ссылки, либо вообще ничего не создано.

Теперь в методе сохранения происходит реальное действие.Я бы использовал регулярные выражения, чтобы вытащить все ссылки, а затем работать через них одну за другой.

  1. Для каждой ссылки необходимо определить модель, с которой связан.Это было бы легко с помощью словаря моделей с указанием их имен.
  2. Необходимо определить, действительно ли ссылка идентифицировала действительный экземпляр модели.Если нет, либо пропустите эту ссылку, либо создайте исключение и удалите его из всего процесса (см. Выше относительно транзакций).
  3. Вам необходимо создать ссылки.Увидеть ниже.

В Django есть стандартный механизм для общих внешних ключей , который вы обязательно должны использовать здесь.Вы можете создать класс ссылок что-то вроде:

class Link(models.Model):
    # link to particular task:
    task = models.ForeignKey(Task)

    # these three fields together set up a generic foreign key which 
    # represents the object you're linking to:
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')

Ваши объекты модели Task будут автоматически получать атрибут с именем link_set, который будет списком экземпляров Link.

Создание ссылки будет выглядеть примерно так:

# encountered a description with [[User:43]]
instance = User.objects.get(pk=43)
link = Link.objects.create(task=my_task_object, content_object=instance)

Если присвоить атрибуту Link content_object экземпляр другой модели, его поля content_type и object_id автоматически заполняются длявы, и ваша ссылка будет преобразована обратно в указанный экземпляр.

Надеюсь, что это полезно.Запросите более подробную информацию, если вам это нужно.

...