Django Schema Explorer простой рекурсивный алгоритм - путать с результатами / как исправить - PullRequest
0 голосов
/ 07 апреля 2020

Я использую Django и у меня есть несколько вариантов использования, для которых требуется возможность для объектов отслеживать свои отношения через несколько моделей. Я не хочу вручную кодировать эту функциональность для каждой модели. Некоторые примеры моделей:

class Project(models.Model):
    project_name = models.CharField(max_length=200, default="development_project")

class Question(models.Model):
    project = models.ForeignKey(Project, default=1, on_delete=models.CASCADE)
    question_text = models.CharField(max_length=200, default="question text")

class Extra(models.Model):
    extended_q = models.ForeignKey(Question, default=1, on_delete=models.CASCADE)
    summary_of = models.ForeignKey(Question, default=1, on_delete=models.CASCADE)
    content    = models.CharField(max_length=200, default="simple summary")

class Answer(models.Model):
    question = models.ForeignKey(Question, default=1, on_delete=models.CASCADE)
    user     = models.ForeignKey(User, default=1, on_delete=models.CASCADE)

Использование моделей в качестве узлов сети и отношений в качестве ребер, кажется, что это должно быть управляемым, но для некоторой сложности, где есть «избыточные» ребра - мы разрешаем дополнительный суммировать ответы из другого проекта?

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

  1. класс models.Manager, который может выступать в качестве менеджера по умолчанию для подкласса Django приложения, которые работают вместе на едином сайте и помогают осуществлять управление разделением строк, которое не позволит пользователям, даже администраторам, оказаться под ногами друг друга.
  2. общее приложение, использующее ContentTypes, которое может помочь Пользователь создает наборы данных и организует таблицы для фреймов данных (принимая fks и присваивая им соответствующие переменные категории и т. д. c).

Django предоставляет очень хорошие дескрипторы от одной модели к другой, поэтому я пытаясь использовать эти свойства в очень маленькой функции, полученной из find_all_paths: python паттернов, эссе

def fap(start, goal, path=[]):
path = path + [start]
if start == goal:
    return path
paths = []
neighbour_list = [fk for fk in start._meta.get_fields() \
           if (fk.concrete and fk.many_to_one and not fk.remote_field.model == start)]
for neighbour in neighbour_list:
    if neighbour not in path:
        path.append(neighbour)
        newpaths = fap(neighbour.remote_field.model, goal, path)
        for newpath in newpaths:
            paths.append(newpath)
return [paths]

Результаты:

> h = fap(e,a)
> h
[[
[<class 'polls.models.Extra'>, <django.db.models.fields.related.ForeignKey: extended_question>, <class 'polls.models.Question'>, <django.db.models.fields.related.ForeignKey: project>, <class 'polls.models.Project'>],
[<class 'polls.models.Extra'>, <django.db.models.fields.related.ForeignKey: extended_question>, <django.db.models.fields.related.ForeignKey: summary_of>, <class 'polls.models.Question'>, <django.db.models.fields.related.ForeignKey: project>, <class 'polls.models.Project'>]
]]

Это близко, но если вы посмотрите на второй список, он содержит оба поля FK от Extra до Question. Учитывая, что первый список содержит только «extended_question», было бы неплохо, если бы второй список содержал только «summary_of», но, честно говоря, после того, как вы поразительно долго ткнули в это, я выхожу пустым. Второй список создается первым, и его можно было бы использовать, если бы он был единственным результатом - мне просто нужно было бы интерпретировать список (который будет чередовать модель / поле / модель / поле для одного пути, а двойные поля означают избыточные ребра); но тогда первый список, который содержит только extended_question, плох, потому что 'extended_question' уже был во втором списке, когда он был создан.

Есть ли кусок 1030 *, который я пропустил, или что-то явно неработающее о создании списка с узлами и ребрами?

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