コード例 #1
0
ファイル: sources.py プロジェクト: a59/geneapro
def extended_sources(ids, schemes):
    """Return a dict of Source instances, with extra attributes
       :param schemes:
           Either None or a set. If specified, it will contain the set of
           surety schemes necessary to represent the assertions.
    """

    assert (isinstance(ids, list))
    assert schemes is None or isinstance(schemes, set)

    sources = dict()  # id -> Source

    for s in sql_in(
            models.Source.objects.select_related("repositories", "researcher"),
            "id", ids):
        sources[s.id] = s
        s.asserts = []

    # Assertions deducted from this source

    p2e = models.P2E.objects.select_related()
    for c in sql_in(p2e, "source", ids):
        sources[c.source_id].asserts.append(c)
        if schemes is not None:
            schemes.add(c.surety.scheme_id)

    p2c = models.P2C.objects.select_related()
    for c in sql_in(p2c, "source", ids):
        sources[c.source_id].asserts.append(c)

        if schemes is not None:
            schemes.add(c.surety.scheme_id)

    return sources
コード例 #2
0
def extended_events(ids):
    """Return a dict of Event instances, augmented with the following fields:
        - "p2e": a list of instances of P2E for this event
    """

    assert (isinstance(ids, list))

    events = dict()  # id -> ExtendedEvent
    p2e = models.P2E.objects.select_related()
    for a in sql_in(p2e, "event", ids):
        assert isinstance(a, models.P2E)

        ev = events.get(a.event_id, {'p2e': []})
        events[a.event_id] = ev

        p2e = {
            'disproved': a.disproved,
            'rationale': a.rationale,
            'role_name': a.role.name,
            'person': {
                'name': a.person.name,
                'id': a.person_id
            },
            'surety': a.surety_id,
            'source': {
                'id': a.source_id
            }
        }
        ev['p2e'].append(p2e)

    return events
コード例 #3
0
ファイル: events.py プロジェクト: a59/geneapro
def extended_events(ids):
    """Return a dict of Event instances, augmented with the following fields:
        - "p2e": a list of instances of P2E for this event
    """

    assert(isinstance(ids, list))

    events = dict()  # id -> ExtendedEvent
    p2e = models.P2E.objects.select_related()
    for a in sql_in(p2e, "event", ids):
        assert isinstance(a, models.P2E)

        ev = events.get(a.event_id, {'p2e': []})
        events[a.event_id] = ev

        p2e = {
            'disproved': a.disproved,
            'rationale': a.rationale,
            'role_name': a.role.name,
            'person': {
                'name': a.person.name,
                'id': a.person_id
            },
            'surety': a.surety_id,
            'source': {
                'id': a.source_id
            }
        }
        ev['p2e'].append(p2e)

    return events
コード例 #4
0
ファイル: events.py プロジェクト: HairyDude/geneapro
def extended_events(ids):
    """Return a dict of Event instances, augmented with the following fields:
        - "p2e": a list of instances of P2E for this event
    """

    assert(isinstance(ids, list))

    events = dict()  # id -> ExtendedEvent
    p2e = models.P2E.objects.select_related()
    for a in sql_in(p2e, "event", ids):
        events[a.event_id] = ev = events.get(a.event_id, a.event)
        p = ev.p2e = getattr(ev, "p2e", [])
        p.append(a)

    return events
コード例 #5
0
def extended_personas(
    nodes, styles, graph, p2e=None, event_types=None, schemes=None,
    p2c=None, p2g=None,
    all_sources=None, as_css=False, query_groups=True):
    """
    Compute the events for the various persons in `nodes` (all all persons in
    the database if None)
    Return a dict indexed on id containing extended instances of Persona,
    with additional fields for the birth, the death,...

       :param nodes:
           A set of graph.Persona_node, or None to get all persons from the
           database.
       :param graph: an instance of Graph, which is used to compute whether
          two ids represent the same person.
       :param dict all_sources: either a dictionary, or None. If specified, it
          will be filled with  "sourceId -> models.Source" objects
       :param as_css:
          True to get the styles as a CSS string rather than a python dict
       :param event_types: restricts the types of events that are retrieved
       :param dict p2e: All person-to-event assertions
       :param dict p2c: All persona-to-characteristic assertions
       :param dict p2g: All persona-to-group assertions
       :return: a list of persons:
          * persons is a dictionary of Persona instances, indexed on persona_id

       SCHEMES is the list of ids of Surety_Scheme that are used. You
          should pass a set() if you are interested in this. Otherwise, it is
          just discarded.

       This sets persons[*].chars to a list of the characteristics.
       Only the events of type in TYPES are returned
    """
    if nodes:
        ids = [a.main_id for a in nodes]
    else:
        ids = None

    compute_parts = styles and styles.need_place_parts()

    roles = dict()  # role_id  -> name
    places = dict()  # place_id -> place

    assert(schemes is None or isinstance(schemes, set))

    if styles:
        styles.start()

    # Get the role names

    for role in models.Event_Type_Role.objects.all():
        roles[role.id] = role.name

    ##############
    # Create the personas that will be returned.
    ##############

    persons = dict()  # id -> person
    if ids:
        for p in sql_in(models.Persona.objects, "id", ids):
            # p.id is always the main_id, since that's how ids was built
            persons[p.id] = p
            __add_default_person_attributes(p)
    else:
        for p in models.Persona.objects.all():
            mid = graph.node_from_id(p.id).main_id
            if mid not in persons:
                persons[mid] = p
                __add_default_person_attributes(p)

    ################
    # Check all events that the persons were involved in.
    ################

    events = models.P2E.objects.select_related(
        'event', 'event__place', 'event__type', 'surety')
    if event_types:
        events = events.filter(event__type__in=event_types)

    all_ids = None
    if nodes:
        all_ids = set()
        for p in nodes:
            all_ids.update(p.ids)

    # All query the 'principal' for each events, so that we can provide
    # that information graphically.
    for p in sql_in(events, "person", all_ids):
        e = p.event

        p_node = graph.node_from_id(p.person_id)
        person = persons[p_node.main_id]

        # ??? A person could be involved multiple times in the same
        # event, under multiple roles. Here we are only preserving the
        # last occurrence
        if p2e is not None:
            # ??? Should we reset p.p1, since this is always the same
            p2e[e.id] = p

        if all_sources is not None:
            all_sources.setdefault(p.source_id, {})

        e.Date = e.date and DateRange(e.date)

        if schemes is not None:
            schemes.add(p.surety.scheme_id)

        if compute_parts and e.place:
            places[e.place_id] = e.place

        if styles:
            styles.process(person, p.role_id, e)

        if not p.disproved \
           and p.role_id == models.Event_Type_Role.principal:
            if not e.Date:
                pass
            elif e.type_id == models.Event_Type.birth:
                if person.birth is None \
                   or person.birth.date_sort > e.date_sort:
                    person.birth = e
            elif e.type_id == models.Event_Type.death:
                if person.death is None \
                   or person.death.date_sort < e.date_sort:
                    person.death = e
            elif e.type_id == models.Event_Type.marriage:
                person.marriage = e

    #########
    # Get all groups to which the personas belong
    #########

    if query_groups:
        groups = models.P2G.objects.select_related('group')
        for gr in sql_in(groups, "person", all_ids):
            p_node = graph.node_from_id(gr.person_id)
            person = persons[p_node.main_id]

            if p2g is not None:
                p2g[gr.group_id] = gr
            if all_sources is not None:
                all_sources.setdefault(gr.source_id, {})

            if schemes is not None:
                schemes.add(gr.surety.scheme_id)

    #########
    # Get all characteristics of these personas
    #########

    c2p = dict()  # characteristic_id -> person
    all_p2c = models.P2C.objects.select_related(
        'characteristic', 'characteristic__place')

    for p in sql_in(all_p2c, "person", all_ids):
        c = p.characteristic
        p_node = graph.node_from_id(p.person_id)
        person = persons[p_node.main_id]
        c2p[c.id] = person

        if all_sources is not None:
            all_sources.setdefault(p.source_id, {})

        c.date = c.date and DateRange(c.date)

        if schemes is not None:
            schemes.add(p.surety.scheme_id)

        if p2c is not None:
            # ??? Should we reset p.person, since this is always the same
            # ??? but can't set it to None in the model
            p2c[c.id] = p

        if compute_parts and c.place:
            places[c.place_id] = c.place

    chars = models.Characteristic_Part.objects.select_related(
        'type', 'characteristic', 'characteristic__place')

    for part in sql_in(chars, "characteristic", nodes and c2p.keys()):
        person = c2p[part.characteristic_id]

        if part.type_id == models.Characteristic_Part_Type.sex:
            person.sex = part.name
        elif part.type_id == models.Characteristic_Part_Type.given_name:
            person.given_name = part.name
        elif part.type_id == models.Characteristic_Part_Type.surname:
            person.surname = part.name

    ########
    # Compute place parts once, to limit the number of queries
    # These are only used for styles, not for actual display, although we
    # could benefit from them.
    ########

    if compute_parts:
        prev_place = None
        d = None

        for p in sql_in(models.Place_Part.objects
                        .order_by('place').select_related('type'),
                        "place", places.keys()):

            # ??? We should also check the parent place to gets its own parts
            if p.place_id != prev_place:
                prev_place = p.place_id
                d = dict()
                setattr(places[prev_place], "parts", d)

            d[p.type.name] = p.name

    ##########
    # Get the title for all sources that are mentioned
    ##########

    if all_sources is not None:
        for s in sql_in(models.Source.objects, "id", all_sources.keys()):
            all_sources[s.id] = s

    ##########
    # Compute the styles
    ##########

    if styles:
        for p in persons.itervalues():
            styles.compute(p, as_css=as_css)

    return persons
コード例 #6
0
ファイル: persona.py プロジェクト: HairyDude/geneapro
def __get_events(nodes, styles, graph, types=None, schemes=None,
                 query_groups=True):
    """Compute the events for the various persons in IDS (all all persons in
       the database if None)
       
       :param nodes:
           A set of graph.Persona_node, or None to get all persons from the
           database.
       :param graph: an instance of Graph, which is used to compute whether
          two ids represent the same person.
       :return: a list of persons:
          * persons is a dictionary of Persona instances, indexed on persona_id

       SCHEMES is the list of ids of Surety_Scheme that are used. You
          should pass a set() if you are interested in this. Otherwise, it is
          just discarded.

       This sets persons[*].chars to a list of the characteristics.
       Only the events of type in TYPES are returned
    """
    if nodes:
        ids = [a.main_id for a in nodes]
    else:
        ids = None

    compute_parts = styles and styles.need_place_parts()

    roles = dict()  # role_id  -> name
    places = dict() # place_id -> place

    assert(schemes is None or isinstance(schemes, set))

    # Get the role names

    for role in models.Event_Type_Role.objects.all():
        roles[role.id] = role.name

    ##############
    # Create the personas that will be returned.
    ##############

    persons = dict() # id -> person
    if ids:
        for p in sql_in(models.Persona.objects, "id", ids):
            # p.id is always the main_id, since that's how ids was built
            persons[p.id] = p
            __add_default_person_attributes(p)
    else:
        for p in models.Persona.objects.all():
            mid = graph.node_from_id(p.id).main_id
            if mid not in persons:
                persons[mid] = p
                __add_default_person_attributes(p)

    ################
    # Check all events that the persons were involved in.
    ################

    events = models.P2E.objects.select_related(
        'event', 'event__place', 'event__type', 'surety')
    if types:
        events = events.filter(event__type__in=types)

    all_ids = None
    if nodes:
        all_ids = set()
        for p in nodes:
            all_ids.update(p.ids)

    all_events = dict()

    # All query the 'principal' for each events, so that we can provide
    # that information graphically.
    for p in sql_in(events, "person", all_ids):
        #or_q=Q(role=models.Event_Type_Role.principal)):
        e = p.event

        p_node = graph.node_from_id(p.person_id)
        person = persons[p_node.main_id]
        person.all_events[e.id] = EventInfo(
            event=e, role=roles[p.role_id], assertion=p)

        e.sources = getattr(e, "sources", set())
        e.sources.add(p.source_id)
        e.Date = e.date and DateRange(e.date)

        if schemes is not None:
            schemes.add(p.surety.scheme_id)

        if compute_parts and e.place:
            places[e.place_id] = e.place

        if styles:
            styles.process(person, p.role_id, e)

        if not p.disproved \
           and p.role_id == models.Event_Type_Role.principal:
            if not e.Date:
                pass
            elif e.type_id == models.Event_Type.birth:
                if person.birth is None \
                   or person.birth.date_sort > e.date_sort:
                    person.birth = e
            elif e.type_id == models.Event_Type.death:
                if person.death is None \
                   or person.death.date_sort < e.date_sort:
                    person.death = e
            elif e.type_id == models.Event_Type.marriage:
                person.marriage = e

    #########
    # Get all groups to which the personas belong
    #########

    if query_groups:
        groups = models.P2G.objects.select_related('group')
        for gr in sql_in(groups, "person", all_ids):
            p_node = graph.node_from_id(gr.person_id)
            person = persons[p_node.main_id]
            person.all_groups[gr.group_id] = GroupInfo(
                group=gr.group, assertion=gr)
            if gr.source_id:
                src = getattr(gr.group, "sources", [])
                src.append(gr.source_id)
                gr.group.sources = src
            gr.group.role = gr.role

            if schemes is not None:
                schemes.add(gr.surety.scheme_id)

    #########
    # Get all characteristics of these personas
    #########

    p2c = dict()  # characteristic_id -> person
    all_p2c = models.P2C.objects.select_related(
        'characteristic', 'characteristic__place')

    for p in sql_in(all_p2c, "person", all_ids):
        c = p.characteristic
        p_node = graph.node_from_id(p.person_id)
        person = persons[p_node.main_id]
        p2c[c.id] = person

        c.sources = getattr(c, "sources", set())
        c.sources.add(p.source_id)
        c.date = c.date and DateRange(c.date)

        if schemes is not None:
            schemes.add(p.surety.scheme_id)

        person.all_chars[c.id] = CharInfo(
            char=c,
            assertion=p,
            parts=[])

        if compute_parts and c.place:
            places[c.place_id] = c.place

    chars = models.Characteristic_Part.objects.select_related(
        'type', 'characteristic', 'characteristic__place')

    for part in sql_in(chars, "characteristic", nodes and p2c.keys()):
        person = p2c[part.characteristic_id]
        ch = person.all_chars[part.characteristic_id]
        ch.parts.append(CharPartInfo(name=part.type.name, value=part.name))

        if part.type_id == models.Characteristic_Part_Type.sex:
           person.sex = part.name
        elif part.type_id == models.Characteristic_Part_Type.given_name:
           person.given_name = part.name
        elif part.type_id == models.Characteristic_Part_Type.surname:
           person.surname = part.name

    ########
    # Compute place parts once, to limit the number of queries
    # These are only used for styles, not for actual display, although we
    # could benefit from them.
    ########

    if compute_parts:
       prev_place = None
       d = None

       for p in sql_in(models.Place_Part.objects
           .order_by('place').select_related('type'),
           "place", places.keys()):

          # ??? We should also check the parent place to gets its own parts
          if p.place_id != prev_place:
             prev_place = p.place_id
             d = dict()
             setattr(places[prev_place], "parts", d)

          d[p.type.name] = p.name

    return persons
コード例 #7
0
def __get_events(nodes,
                 styles,
                 graph,
                 types=None,
                 schemes=None,
                 query_groups=True):
    """Compute the events for the various persons in IDS (all all persons in
       the database if None)

       :param nodes:
           A set of graph.Persona_node, or None to get all persons from the
           database.
       :param graph: an instance of Graph, which is used to compute whether
          two ids represent the same person.
       :return: a list of persons:
          * persons is a dictionary of Persona instances, indexed on persona_id

       SCHEMES is the list of ids of Surety_Scheme that are used. You
          should pass a set() if you are interested in this. Otherwise, it is
          just discarded.

       This sets persons[*].chars to a list of the characteristics.
       Only the events of type in TYPES are returned
    """
    if nodes:
        ids = [a.main_id for a in nodes]
    else:
        ids = None

    compute_parts = styles and styles.need_place_parts()

    roles = dict()  # role_id  -> name
    places = dict()  # place_id -> place

    assert (schemes is None or isinstance(schemes, set))

    # Get the role names

    for role in models.Event_Type_Role.objects.all():
        roles[role.id] = role.name

    ##############
    # Create the personas that will be returned.
    ##############

    persons = dict()  # id -> person
    if ids:
        for p in sql_in(models.Persona.objects, "id", ids):
            # p.id is always the main_id, since that's how ids was built
            persons[p.id] = p
            __add_default_person_attributes(p)
    else:
        for p in models.Persona.objects.all():
            mid = graph.node_from_id(p.id).main_id
            if mid not in persons:
                persons[mid] = p
                __add_default_person_attributes(p)

    ################
    # Check all events that the persons were involved in.
    ################

    events = models.P2E.objects.select_related('event', 'event__place',
                                               'event__type', 'surety')
    if types:
        events = events.filter(event__type__in=types)

    all_ids = None
    if nodes:
        all_ids = set()
        for p in nodes:
            all_ids.update(p.ids)

    all_events = dict()

    # All query the 'principal' for each events, so that we can provide
    # that information graphically.
    for p in sql_in(events, "person", all_ids):
        # or_q=Q(role=models.Event_Type_Role.principal)):
        e = p.event

        p_node = graph.node_from_id(p.person_id)
        person = persons[p_node.main_id]
        person.all_events[e.id] = EventInfo(event=e,
                                            role=roles[p.role_id],
                                            assertion=p)

        e.sources = getattr(e, "sources", set())
        e.sources.add(p.source_id)
        e.Date = e.date and DateRange(e.date)

        if schemes is not None:
            schemes.add(p.surety.scheme_id)

        if compute_parts and e.place:
            places[e.place_id] = e.place

        if styles:
            styles.process(person, p.role_id, e)

        if not p.disproved \
           and p.role_id == models.Event_Type_Role.principal:
            if not e.Date:
                pass
            elif e.type_id == models.Event_Type.birth:
                if person.birth is None \
                   or person.birth.date_sort > e.date_sort:
                    person.birth = e
            elif e.type_id == models.Event_Type.death:
                if person.death is None \
                   or person.death.date_sort < e.date_sort:
                    person.death = e
            elif e.type_id == models.Event_Type.marriage:
                person.marriage = e

    #########
    # Get all groups to which the personas belong
    #########

    if query_groups:
        groups = models.P2G.objects.select_related('group')
        for gr in sql_in(groups, "person", all_ids):
            p_node = graph.node_from_id(gr.person_id)
            person = persons[p_node.main_id]
            person.all_groups[gr.group_id] = GroupInfo(group=gr.group,
                                                       assertion=gr)
            if gr.source_id:
                src = getattr(gr.group, "sources", [])
                src.append(gr.source_id)
                gr.group.sources = src
            gr.group.role = gr.role

            if schemes is not None:
                schemes.add(gr.surety.scheme_id)

    #########
    # Get all characteristics of these personas
    #########

    p2c = dict()  # characteristic_id -> person
    all_p2c = models.P2C.objects.select_related('characteristic',
                                                'characteristic__place')

    for p in sql_in(all_p2c, "person", all_ids):
        c = p.characteristic
        p_node = graph.node_from_id(p.person_id)
        person = persons[p_node.main_id]
        p2c[c.id] = person

        c.sources = getattr(c, "sources", set())
        c.sources.add(p.source_id)
        c.date = c.date and DateRange(c.date)

        if schemes is not None:
            schemes.add(p.surety.scheme_id)

        person.all_chars[c.id] = CharInfo(char=c, assertion=p, parts=[])

        if compute_parts and c.place:
            places[c.place_id] = c.place

    chars = models.Characteristic_Part.objects.select_related(
        'type', 'characteristic', 'characteristic__place')

    for part in sql_in(chars, "characteristic", nodes and p2c.keys()):
        person = p2c[part.characteristic_id]
        ch = person.all_chars[part.characteristic_id]
        ch.parts.append(CharPartInfo(name=part.type.name, value=part.name))

        if part.type_id == models.Characteristic_Part_Type.sex:
            person.sex = part.name
        elif part.type_id == models.Characteristic_Part_Type.given_name:
            person.given_name = part.name
        elif part.type_id == models.Characteristic_Part_Type.surname:
            person.surname = part.name

    ########
    # Compute place parts once, to limit the number of queries
    # These are only used for styles, not for actual display, although we
    # could benefit from them.
    ########

    if compute_parts:
        prev_place = None
        d = None

        for p in sql_in(
                models.Place_Part.objects.order_by('place').select_related(
                    'type'), "place", places.keys()):

            # ??? We should also check the parent place to gets its own parts
            if p.place_id != prev_place:
                prev_place = p.place_id
                d = dict()
                setattr(places[prev_place], "parts", d)

            d[p.type.name] = p.name

    return persons
コード例 #8
0
ファイル: persona.py プロジェクト: sam-m888/geneapro
def extended_personas(
        nodes, styles, graph, asserts=None, event_types=None, schemes=None,
        as_css=False, query_groups=True):
    """
    Compute the events for the various persons in `nodes` (all all persons in
    the database if None)
    Return a dict indexed on id containing extended instances of Persona,
    with additional fields for the birth, the death,...

       :param nodes:
           A set of graph.Persona_node, or None to get all persons from the
           database.
       :param graph: an instance of Graph, which is used to compute whether
          two ids represent the same person.
       :param as_css:
          True to get the styles as a CSS string rather than a python dict
       :param event_types: restricts the types of events that are retrieved
       :param list asserts: All assertions
       :return: a list of persons:
          * persons is a dictionary of Persona instances, indexed on persona_id

       SCHEMES is the list of ids of Surety_Scheme that are used. You
          should pass a set() if you are interested in this. Otherwise, it is
          just discarded.

       This sets persons[*].chars to a list of the characteristics.
       Only the events of type in TYPES are returned
    """
    if nodes:
        ids = [a.main_id for a in nodes]
    else:
        ids = None

    compute_parts = styles and styles.need_place_parts()

    roles = dict()  # role_id  -> name

    assert schemes is None or isinstance(schemes, set)

    if styles:
        styles.start()

    # Get the role names

    logger.debug('MANU getting role names')
    for role in models.Event_Type_Role.objects.all():
        roles[role.id] = role.name

    ##############
    # Create the personas that will be returned.
    ##############

    persons = dict()  # id -> person
    if ids:
        for p in sql_in(models.Persona.objects, "id", ids):
            # p.id is always the main_id, since that's how ids was built
            persons[p.id] = p
            __add_default_person_attributes(p)
    else:
        for p in models.Persona.objects.all():
            mid = graph.node_from_id(p.id).main_id
            if mid not in persons:
                persons[mid] = p
                __add_default_person_attributes(p)

    logger.debug('MANU retrieve personas')

    ################
    # Check all events that the persons were involved in.
    ################

    events = models.P2E.objects.select_related(
        'event', 'event__type', *models.P2E.related_json_fields())
    if event_types:
        events = events.filter(event__type__in=event_types)

    all_ids = None
    if nodes:
        all_ids = set()
        for p in nodes:
            all_ids.update(p.ids)

    logger.debug('MANU about to retrieve events')

    birth = None
    death = None

    # Also query the 'principal' for each events, so that we can provide
    # that information graphically.

    for p in sql_in(events, "person", all_ids):
        e = p.event

        p_node = graph.node_from_id(p.person_id)
        person = persons[p_node.main_id]

        # ??? A person could be involved multiple times in the same
        # event, under multiple roles. Here we are only preserving the
        # last occurrence
        if asserts is not None:
            asserts.append(p)

        # ??? Could we take advantage of the e.date_sort string, instead
        # of reparsing the DateRange ?
        e.Date = e.date and DateRange(e.date)

        if schemes is not None:
            schemes.add(p.surety.scheme_id)

        if styles:
            styles.process(person, p.role_id, e)

        if not p.disproved \
           and p.role_id == models.Event_Type_Role.PK_principal:
            if not e.Date:
                pass
            elif e.type_id == models.Event_Type.PK_birth:
                if birth is None or more_recent(birth, e):
                    person.birthISODate = e.date_sort
            elif e.type_id == models.Event_Type.PK_death:
                if death is None or more_recent(death, e):
                    person.deathISODate = e.date_sort
            elif e.type_id == models.Event_Type.PK_marriage:
                person.marriageISODate = e.date_sort

    logger.debug('MANU done processing events')

    #########
    # Get all groups to which the personas belong
    #########

#    if query_groups:
#        groups = models.P2G.objects.select_related(
#            *models.P2G.related_json_fields())
#
#        for gr in sql_in(groups, "person", all_ids):
#            p_node = graph.node_from_id(gr.person_id)
#            person = persons[p_node.main_id]
#
#            if asserts is not None:
#                asserts.append(gr)
#
#            if schemes is not None:
#                schemes.add(gr.surety.scheme_id)

    #########
    # Get all characteristics of these personas
    #########

    if asserts:
        asserts.extend(sql_in(
            models.P2C.objects.select_related(*models.P2C.related_json_fields()),
            "person",
            all_ids))

#    logger.debug('MANU processing p2c')
#    c2p = dict()  # characteristic_id -> person
#    all_p2c = models.P2C.objects.select_related(
#        *models.P2C.related_json_fields())
#
#    for p in sql_in(all_p2c, "person", all_ids):
#        c = p.characteristic
#        p_node = graph.node_from_id(p.person_id)
#        person = persons[p_node.main_id]
#        c2p[c.id] = person
#
#        c.date = c.date and DateRange(c.date)
#
#        if schemes is not None:
#            schemes.add(p.surety.scheme_id)
#
#        if asserts is not None:
#            asserts.append(p)

#    logger.debug('MANU processing characteristic parts')
#
#    chars = models.Characteristic_Part.objects.select_related(
#        'type', 'characteristic').filter(
#            type__in=(models.Characteristic_Part_Type.PK_sex, )).order_by()
#
#    for part in sql_in(chars, "characteristic", nodes and c2p):
#        person = c2p[part.characteristic_id]
#
#        if part.type_id == models.Characteristic_Part_Type.PK_sex:
#            person.sex = part.name

    ########
    # Compute place parts once, to limit the number of queries
    # These are only used for styles, not for actual display, although we
    # could benefit from them.
    ########

#    logger.debug('MANU processing places')
#
#    if compute_parts:
#        prev_place = None
#        d = None
#
#        for p in sql_in(models.Place_Part.objects
#                        .order_by('place').select_related('type'),
#                        "place", places):
#
#            # ??? We should also check the parent place to gets its own parts
#            if p.place_id != prev_place:
#                prev_place = p.place_id
#                d = dict()
#                setattr(places[prev_place], "parts", d)
#
#            d[p.type.name] = p.name

    ##########
    # Compute the styles
    ##########

    if styles:
        logger.debug('MANU compute styles')
        for p in persons.values():
            styles.compute(p, as_css=as_css)

    return persons