Files
social-graph/backend/contacts/serializers.py
T
gitrusprusandCursor 5155b3a37a Add multiple network maps, graph UX improvements, and full backup import.
Support per-map contact membership with scoped graph views, relation editing on edges, layout caching, and automatic detection of full JSON backups so contacts and relations import together.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-24 17:54:51 +03:00

108 lines
3.5 KiB
Python

from rest_framework import serializers
from .models import Contact, Relation, NetworkMap, NetworkMapMembership
class ContactSerializer(serializers.ModelSerializer):
relations_count = serializers.SerializerMethodField()
class Meta:
model = Contact
fields = [
'id', 'name', 'email', 'phone',
'organization', 'position', 'notes',
'created_at', 'updated_at', 'relations_count',
]
read_only_fields = ['id', 'created_at', 'updated_at', 'relations_count']
def get_relations_count(self, obj):
return (
obj.relations_as_source.count() +
obj.relations_as_target.count()
)
class RelationSerializer(serializers.ModelSerializer):
source_name = serializers.CharField(source='source.name', read_only=True)
target_name = serializers.CharField(source='target.name', read_only=True)
class Meta:
model = Relation
fields = [
'id', 'source', 'source_name',
'target', 'target_name',
'relation_type', 'description', 'interaction_intensity',
'created_at',
]
read_only_fields = ['id', 'created_at', 'source_name', 'target_name']
def validate(self, data):
if data.get('source') == data.get('target'):
raise serializers.ValidationError(
'Нельзя создать связь контакта с самим собой.'
)
return data
class NetworkMapSerializer(serializers.ModelSerializer):
memberships_count = serializers.SerializerMethodField()
class Meta:
model = NetworkMap
fields = [
'id', 'name', 'description',
'created_at', 'updated_at', 'memberships_count',
]
read_only_fields = ['id', 'created_at', 'updated_at', 'memberships_count']
def get_memberships_count(self, obj):
return obj.memberships.count()
class NetworkMapMembershipSerializer(serializers.ModelSerializer):
contact_name = serializers.CharField(source='contact.name', read_only=True)
map_name = serializers.CharField(source='map.name', read_only=True)
class Meta:
model = NetworkMapMembership
fields = [
'id', 'map', 'map_name', 'contact', 'contact_name',
'life_sphere', 'network_circle', 'importance',
'map_angle', 'map_radius_ratio',
'created_at', 'updated_at',
]
read_only_fields = ['id', 'created_at', 'updated_at', 'contact_name', 'map_name']
class GraphSerializer(serializers.Serializer):
"""Граф для vis.js: nodes + edges."""
nodes = serializers.SerializerMethodField()
edges = serializers.SerializerMethodField()
def get_nodes(self, obj):
contacts = Contact.objects.all()
return [
{
'id': c.id,
'label': c.name,
'title': f'{c.organization}\n{c.position}'.strip() or c.name,
'group': c.organization or 'default',
}
for c in contacts
]
def get_edges(self, obj):
relations = Relation.objects.select_related('source', 'target').all()
return [
{
'id': r.id,
'from': r.source_id,
'to': r.target_id,
'label': r.get_relation_type_display(),
'title': r.description or r.get_relation_type_display(),
'relation_type': r.relation_type,
'interaction_intensity': r.interaction_intensity,
}
for r in relations
]