def annotated_ancestors(self): '''Returns a list of this person's ancestors annotated with the name of the relationship to this person and the distance between them (so a list of (Person, relationship, distance) tuples).''' distances = self._ancestor_distances() ancestors = [] for ancestor in distances.keys(): relationship = describe_relative(self, ancestor, distances, {}) ancestors.append((ancestor, relationship, distances[ancestor])) ancestors.sort(key=lambda x: (x[2], x[1], x[0].surname)) return ancestors
def annotated_descendants(self): '''Returns a list of this person's descendants annotated with the name of the relationship to this person (so a list of (Person, relationship) tuples.''' distances = self._descendant_distances() descendants = [] for descendant in distances.keys(): relationship = describe_relative(self, descendant, {}, descendant._ancestor_distances()) descendants.append((descendant, relationship, distances[descendant])) descendants.sort(key=lambda x: (x[2], x[1], x[0].surname)) return descendants
def person(request, person_id): person = get_object_or_404(Person, id=person_id) relationship = describe_relative( request.user.person, person, request.user.person._ancestor_distances(), person._ancestor_distances()) if request.user.person else None return render( request, 'people/person.html', { 'person': person, 'descendants': len(list(person.descendants())), 'ancestors': len(list(person.ancestors())), 'relationship': relationship, 'list': Person.objects.select_related('birth') })
def person(request, person_id): person = get_object_or_404(Person, id=person_id) relationship = describe_relative(request.user.person, person, request.user.person._ancestor_distances(), person._ancestor_distances()) if request.user.person else None return render(request, 'people/person.html', {'person': person, 'descendants': len(list(person.descendants())), 'ancestors': len(list(person.ancestors())), 'relationship': relationship, 'list': Person.objects.select_related('birth')})
def annotated_relatives(self): '''Returns a list of all of this person's blood relatives. The first item in each tuple is the person, the second is the relationship, and the third is the distance between the two individuals.''' ancestor_distances = self._ancestor_distances() distances = ancestor_distances.copy() distances.update(self._descendant_distances()) annotated = [] for relative in self.relatives(): distance = distances.get(relative, None) relative_distances = relative._ancestor_distances() if not distance: (_, d1, d2) = closest_common_ancestor(ancestor_distances, relative_distances) distance = max(d1, d2) relationship = describe_relative(self, relative, ancestor_distances, relative_distances) annotated.append((relative, relationship, distance)) annotated.sort(key=lambda x: (x[2], x[1], x[0].surname)) return annotated
def annotated_descendants2(self): '''Returns a list of this person's descendants annotated with the name of the relationship to this person and distance. Suitable for d3.js tree charts''' distances = self._descendant_distances() descendants = [] for descendant in distances.keys(): relationship = describe_relative(self, descendant, {}, descendant._ancestor_distances()) descendants.append({ "name": descendant.name(), "avatar": str(descendant.avatar), "mother_id": descendant.mother_id, "father_id": descendant.father_id, "id": descendant.id, "relationship": relationship, "distance": distances[descendant] }) #descendants.sort(key=lambda x: (x[2], x[1], x[0].surname)) return descendants