def METHOD_NAME(self, question_graph):
    # Given the graph of questions:
    # - check that first_question is not None/null, otherwise return empty queryset
    # - retrieve all edges in one go (possibly do a count first and fail if too many ...)
    # - if there is a first question and there are no edges: return queryset with only first question
    # - construct a directed graph
    # - check that first question is a node in that graph, if not only return first question
    # - get the set of "descendants" of first question in the graph, turn it into a queryset and return it
    from signals.apps.questionnaires.models import Edge
    MAX_QUESTIONS = 50
    # No first question: return empty Question queryset
    if not question_graph.first_question:
        return self.none()
    # No edges: return Queryset with only the first question
    edges = Edge.objects.filter(graph=question_graph)
    if not edges.exists():
        return self.filter(id=question_graph.first_question_id)
    # first question and edges present, build directed graph
    nx_graph = networkx.DiGraph()
    for edge in edges:
        nx_graph.add_edge(edge.question_id, edge.next_question_id)
        if len(nx_graph) > MAX_QUESTIONS:
            msg = f'Question graph {question_graph.name} contains too many questions.'
            raise Exception(msg)
    # Our first_question should be part of the graph of questions, if it is
    # not only the first_question is reachable.
    if question_graph.first_question_id not in nx_graph:
        return self.filter(id=question_graph.first_question_id)
    # our question graph must be directed and acyclic
    if not networkx.is_directed_acyclic_graph(nx_graph):
        msg = f'Question graph {question_graph.name} not acyclic.'
        raise Exception(msg)
    # only questions reachable from the first_question node are of interest
    reachable = networkx.descendants(nx_graph, question_graph.first_question_id)
    reachable.add(question_graph.first_question_id)
    return self.filter(id__in=reachable)