feat: add configurable people maps
Add independent map profiles, offline city lookup, bundled world artwork and collision-free portrait placement with optional person details. Deploy with updated requirements, migrations 0029-0031 and collectstatic.
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
# Generated by Django 5.2.16 on 2026-11-02 19:44
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('pages', '0028_alter_blogpostpartner_options_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='MapPerson',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=200)),
|
||||
('qualifications', models.CharField(blank=True, max_length=100)),
|
||||
('role', models.CharField(blank=True, max_length=200)),
|
||||
('institution', models.CharField(blank=True, max_length=300)),
|
||||
('biography', models.TextField(blank=True)),
|
||||
('photo', models.ImageField(blank=True, upload_to='maps/people/')),
|
||||
('profile_url', models.URLField(blank=True)),
|
||||
],
|
||||
options={
|
||||
'verbose_name_plural': 'Map people',
|
||||
'ordering': ['name', 'pk'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='PeopleMap',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('title', models.CharField(max_length=200)),
|
||||
('description', models.TextField(blank=True)),
|
||||
('style', models.CharField(choices=[('aurora', 'Aurora — dark ocean'), ('paper', 'Atlas — light'), ('classic', 'Classic — original blue / turquoise palette')], default='aurora', max_length=20)),
|
||||
('background_image', models.ImageField(blank=True, help_text='Optional original map artwork. Must use an equirectangular world projection.', upload_to='maps/')),
|
||||
('is_active', models.BooleanField(default=True)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='MapPlacement',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('page_path', models.CharField(help_text='Local page path, e.g. /about/, /projects/project-slug/, or any custom page. No domain or query string.', max_length=400)),
|
||||
('position', models.CharField(choices=[('top', 'Before page content'), ('bottom', 'After page content')], default='bottom', max_length=10)),
|
||||
('order', models.PositiveIntegerField(default=0)),
|
||||
('is_active', models.BooleanField(default=True)),
|
||||
('people_map', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='placements', to='pages.peoplemap')),
|
||||
],
|
||||
options={
|
||||
'ordering': ['order', 'pk'],
|
||||
'constraints': [models.UniqueConstraint(fields=('people_map', 'page_path', 'position'), name='unique_map_placement')],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='MapMembership',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('location_method', models.CharField(choices=[('city', 'Country and city'), ('coordinates', 'Coordinates')], default='city', max_length=12)),
|
||||
('country', models.CharField(blank=True, max_length=100)),
|
||||
('city', models.CharField(blank=True, max_length=100)),
|
||||
('latitude', models.FloatField(blank=True, null=True)),
|
||||
('longitude', models.FloatField(blank=True, null=True)),
|
||||
('order', models.PositiveIntegerField(default=0)),
|
||||
('person', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='map_memberships', to='pages.mapperson')),
|
||||
('people_map', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='memberships', to='pages.peoplemap')),
|
||||
],
|
||||
options={
|
||||
'ordering': ['order', 'pk'],
|
||||
'constraints': [models.UniqueConstraint(fields=('people_map', 'person'), name='unique_map_person')],
|
||||
},
|
||||
),
|
||||
]
|
||||
Reference in New Issue
Block a user