d4ec85add4
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.
76 lines
4.2 KiB
Python
76 lines
4.2 KiB
Python
# 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')],
|
|
},
|
|
),
|
|
]
|