Cleanup: remove tracked pycache and db.sqlite3; add map membership backfill, new components, backups, docs

This commit is contained in:
gitrusprus
2026-06-28 22:16:01 +03:00
parent 4eb4c145b6
commit ce4e9ac5e6
46 changed files with 12125 additions and 176 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,62 @@
from contacts.models import Contact, NetworkMap, NetworkMapMembership, Relation
def contact_ids_from_relations(relations_qs):
contact_ids = set()
for relation in relations_qs.only('source_id', 'target_id'):
contact_ids.add(relation.source_id)
contact_ids.add(relation.target_id)
return contact_ids
def backfill_map_memberships_for_owner(owner):
"""Добавляет на первую карту владельца контакты из его связей, если участников ещё нет."""
if owner is None:
maps = NetworkMap.objects.filter(owner__isnull=True).order_by('id')
relations = Relation.objects.filter(owner__isnull=True)
else:
maps = NetworkMap.objects.filter(owner=owner).order_by('id')
relations = Relation.objects.filter(owner=owner)
if not maps.exists():
return 0
if NetworkMapMembership.objects.filter(map__in=maps).exists():
return 0
contact_ids = contact_ids_from_relations(relations)
if not contact_ids:
return 0
if owner is None:
contacts = Contact.objects.filter(id__in=contact_ids, owner__isnull=True)
else:
contacts = Contact.objects.filter(id__in=contact_ids, owner=owner)
target_map = maps.first()
created = 0
for contact in contacts:
_, was_created = NetworkMapMembership.objects.get_or_create(
map=target_map,
contact=contact,
defaults={
'life_sphere': 'other',
'network_circle': 'productivity',
'importance': 3,
'conflict_involvement': 3,
},
)
if was_created:
created += 1
return created
def backfill_all_map_memberships():
from django.contrib.auth import get_user_model
User = get_user_model()
total = 0
total += backfill_map_memberships_for_owner(None)
for user in User.objects.all():
total += backfill_map_memberships_for_owner(user)
return total
@@ -0,0 +1,68 @@
from django.conf import settings
from django.db import migrations
def backfill_memberships(apps, schema_editor):
NetworkMap = apps.get_model('contacts', 'NetworkMap')
NetworkMapMembership = apps.get_model('contacts', 'NetworkMapMembership')
Relation = apps.get_model('contacts', 'Relation')
Contact = apps.get_model('contacts', 'Contact')
User = apps.get_model('auth', 'User')
def backfill_for_owner(owner_id):
if owner_id is None:
maps = NetworkMap.objects.filter(owner__isnull=True).order_by('id')
relations = Relation.objects.filter(owner__isnull=True)
contact_owner_filter = {'owner__isnull': True}
else:
maps = NetworkMap.objects.filter(owner_id=owner_id).order_by('id')
relations = Relation.objects.filter(owner_id=owner_id)
contact_owner_filter = {'owner_id': owner_id}
if not maps.exists():
return 0
if NetworkMapMembership.objects.filter(map__in=maps).exists():
return 0
contact_ids = set()
for relation in relations.only('source_id', 'target_id'):
contact_ids.add(relation.source_id)
contact_ids.add(relation.target_id)
if not contact_ids:
return 0
contacts = Contact.objects.filter(id__in=contact_ids, **contact_owner_filter)
target_map = maps.first()
created = 0
for contact in contacts:
_, was_created = NetworkMapMembership.objects.get_or_create(
map=target_map,
contact=contact,
defaults={
'life_sphere': 'other',
'network_circle': 'productivity',
'importance': 3,
'conflict_involvement': 3,
},
)
if was_created:
created += 1
return created
total = backfill_for_owner(None)
for user in User.objects.all():
total += backfill_for_owner(user.id)
if total:
print(f'Backfilled {total} network map memberships')
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('contacts', '0011_add_owner'),
]
operations = [
migrations.RunPython(backfill_memberships, migrations.RunPython.noop),
]
+1 -1
View File
@@ -142,7 +142,7 @@ class NetworkMapMembershipSerializer(serializers.ModelSerializer):
'map_angle', 'map_radius_ratio',
'created_at', 'updated_at',
]
read_only_fields = ['id', 'created_at', 'updated_at', 'contact_name', 'map_name']
read_only_fields = ['id', 'map', 'created_at', 'updated_at', 'contact_name', 'map_name']
class GraphSerializer(serializers.Serializer):