First commit of claude's rework in django + vanillajs fronted
This commit is contained in:
136
apps/gears/migrations/0001_initial.py
Normal file
136
apps/gears/migrations/0001_initial.py
Normal file
@@ -0,0 +1,136 @@
|
||||
# Generated by Django 4.2.16 on 2026-03-24 09:48
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Gear',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('brand', models.CharField(max_length=100)),
|
||||
('model_name', models.CharField(max_length=150)),
|
||||
('description', models.TextField(blank=True)),
|
||||
('gear_type', models.CharField(choices=[('FIREARM', 'Firearm'), ('SCOPE', 'Scope'), ('SUPPRESSOR', 'Suppressor'), ('BIPOD', 'Bipod'), ('MAGAZINE', 'Magazine')], editable=False, max_length=20)),
|
||||
('status', models.CharField(choices=[('PENDING', 'Pending Verification'), ('VERIFIED', 'Verified'), ('REJECTED', 'Rejected')], default='PENDING', max_length=10)),
|
||||
('reviewed_at', models.DateTimeField(blank=True, null=True)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
],
|
||||
options={
|
||||
'ordering': ['brand', 'model_name'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Rig',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=100)),
|
||||
('description', models.TextField(blank=True)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
],
|
||||
options={
|
||||
'ordering': ['-created_at'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='RigItem',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('role', models.CharField(choices=[('PRIMARY', 'Primary Firearm'), ('OPTIC', 'Optic / Scope'), ('SUPPRESSOR', 'Suppressor'), ('BIPOD', 'Bipod'), ('MAGAZINE', 'Magazine'), ('OTHER', 'Other Accessory')], default='OTHER', max_length=20)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Bipod',
|
||||
fields=[
|
||||
('gear_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='gears.gear')),
|
||||
('min_height_mm', models.DecimalField(blank=True, decimal_places=1, max_digits=6, null=True)),
|
||||
('max_height_mm', models.DecimalField(blank=True, decimal_places=1, max_digits=6, null=True)),
|
||||
('attachment_type', models.CharField(blank=True, choices=[('PICATINNY', 'Picatinny Rail'), ('SLING_STUD', 'Sling Stud'), ('ARCA_SWISS', 'Arca-Swiss'), ('M_LOK', 'M-LOK'), ('KEYMOD', 'KeyMod')], max_length=20)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Bipod',
|
||||
},
|
||||
bases=('gears.gear',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Firearm',
|
||||
fields=[
|
||||
('gear_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='gears.gear')),
|
||||
('firearm_type', models.CharField(choices=[('RIFLE', 'Rifle'), ('PISTOL', 'Pistol'), ('SHOTGUN', 'Shotgun'), ('REVOLVER', 'Revolver'), ('CARBINE', 'Carbine')], max_length=10)),
|
||||
('caliber', models.CharField(max_length=20)),
|
||||
('action', models.CharField(choices=[('BOLT', 'Bolt Action'), ('SEMI_AUTO', 'Semi-Automatic'), ('PUMP', 'Pump Action'), ('LEVER', 'Lever Action'), ('BREAK', 'Break Action'), ('FULL_AUTO', 'Full Automatic')], max_length=10)),
|
||||
('barrel_length_mm', models.DecimalField(blank=True, decimal_places=1, max_digits=6, null=True)),
|
||||
('magazine_capacity', models.PositiveSmallIntegerField(blank=True, null=True)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Firearm',
|
||||
},
|
||||
bases=('gears.gear',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Magazine',
|
||||
fields=[
|
||||
('gear_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='gears.gear')),
|
||||
('caliber', models.CharField(max_length=20)),
|
||||
('capacity', models.PositiveSmallIntegerField()),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Magazine',
|
||||
},
|
||||
bases=('gears.gear',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Scope',
|
||||
fields=[
|
||||
('gear_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='gears.gear')),
|
||||
('magnification_min', models.DecimalField(decimal_places=1, max_digits=5)),
|
||||
('magnification_max', models.DecimalField(decimal_places=1, max_digits=5)),
|
||||
('objective_diameter_mm', models.DecimalField(decimal_places=1, max_digits=5)),
|
||||
('tube_diameter_mm', models.DecimalField(decimal_places=1, default=30, max_digits=5)),
|
||||
('reticle_type', models.CharField(blank=True, choices=[('DUPLEX', 'Duplex'), ('MILDOT', 'Mil-Dot'), ('BDC', 'BDC'), ('ILLUMINATED', 'Illuminated'), ('ETCHED', 'Etched Glass')], max_length=20)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Scope',
|
||||
},
|
||||
bases=('gears.gear',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Suppressor',
|
||||
fields=[
|
||||
('gear_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='gears.gear')),
|
||||
('max_caliber', models.CharField(max_length=20)),
|
||||
('thread_pitch', models.CharField(blank=True, max_length=20)),
|
||||
('length_mm', models.DecimalField(blank=True, decimal_places=1, max_digits=6, null=True)),
|
||||
('weight_g', models.DecimalField(blank=True, decimal_places=1, max_digits=6, null=True)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Suppressor',
|
||||
},
|
||||
bases=('gears.gear',),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='UserGear',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('nickname', models.CharField(blank=True, max_length=100)),
|
||||
('serial_number', models.CharField(blank=True, max_length=100)),
|
||||
('purchase_date', models.DateField(blank=True, null=True)),
|
||||
('notes', models.TextField(blank=True)),
|
||||
('added_at', models.DateTimeField(auto_now_add=True)),
|
||||
('gear', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='user_instances', to='gears.gear')),
|
||||
],
|
||||
options={
|
||||
'ordering': ['-added_at'],
|
||||
},
|
||||
),
|
||||
]
|
||||
65
apps/gears/migrations/0002_initial.py
Normal file
65
apps/gears/migrations/0002_initial.py
Normal file
@@ -0,0 +1,65 @@
|
||||
# Generated by Django 4.2.16 on 2026-03-24 09:48
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('gears', '0001_initial'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='usergear',
|
||||
name='user',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='inventory', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='rigitem',
|
||||
name='rig',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='rig_items', to='gears.rig'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='rigitem',
|
||||
name='user_gear',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='rig_items', to='gears.usergear'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='rig',
|
||||
name='items',
|
||||
field=models.ManyToManyField(related_name='rigs', through='gears.RigItem', to='gears.usergear'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='rig',
|
||||
name='user',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='rigs', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='gear',
|
||||
name='reviewed_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='reviewed_gears', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='gear',
|
||||
name='submitted_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='submitted_gears', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
migrations.AddConstraint(
|
||||
model_name='rigitem',
|
||||
constraint=models.UniqueConstraint(fields=('rig', 'user_gear'), name='unique_gear_per_rig'),
|
||||
),
|
||||
migrations.AddConstraint(
|
||||
model_name='rig',
|
||||
constraint=models.UniqueConstraint(fields=('user', 'name'), name='unique_rig_per_user'),
|
||||
),
|
||||
migrations.AddConstraint(
|
||||
model_name='gear',
|
||||
constraint=models.UniqueConstraint(fields=('brand', 'model_name'), name='unique_gear_brand_model'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,450 @@
|
||||
# Generated by Django 4.2.16 on 2026-03-24 13:42
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('gears', '0002_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Ammo',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('brand', models.CharField(max_length=100, verbose_name='brand')),
|
||||
('name', models.CharField(max_length=150, verbose_name='name')),
|
||||
('caliber', models.CharField(max_length=20, verbose_name='caliber')),
|
||||
('bullet_weight_gr', models.DecimalField(decimal_places=1, max_digits=6, verbose_name='bullet weight (gr)')),
|
||||
('bullet_type', models.CharField(choices=[('FMJ', 'Full Metal Jacket'), ('HP', 'Hollow Point'), ('BTHP', 'Boat Tail Hollow Point'), ('SP', 'Soft Point'), ('HPBT', 'Hollow Point Boat Tail'), ('SMK', 'Sierra MatchKing'), ('A_TIP', 'Hornady A-Tip'), ('MONO', 'Monolithic / Solid')], max_length=5, verbose_name='bullet type')),
|
||||
('primer_size', models.CharField(blank=True, choices=[('SP', 'Small Pistol'), ('LP', 'Large Pistol'), ('SR', 'Small Rifle'), ('LR', 'Large Rifle'), ('LRM', 'Large Rifle Magnum')], max_length=3, verbose_name='primer size')),
|
||||
('case_material', models.CharField(choices=[('BRASS', 'Brass'), ('STEEL', 'Steel'), ('ALUMINUM', 'Aluminum'), ('NICKEL', 'Nickel-Plated Brass')], default='BRASS', max_length=10, verbose_name='case material')),
|
||||
('muzzle_velocity_fps', models.DecimalField(blank=True, decimal_places=1, max_digits=6, null=True, verbose_name='muzzle velocity (fps)')),
|
||||
('muzzle_energy_ftlb', models.DecimalField(blank=True, decimal_places=1, max_digits=7, null=True, verbose_name='muzzle energy (ft·lb)')),
|
||||
('box_count', models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='box count')),
|
||||
('notes', models.TextField(blank=True, verbose_name='notes')),
|
||||
('status', models.CharField(choices=[('PENDING', 'Pending Verification'), ('VERIFIED', 'Verified'), ('REJECTED', 'Rejected')], default='PENDING', max_length=10, verbose_name='status')),
|
||||
('reviewed_at', models.DateTimeField(blank=True, null=True, verbose_name='reviewed at')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='created at')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='updated at')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'ammo',
|
||||
'verbose_name_plural': 'ammo',
|
||||
'ordering': ['brand', 'name', 'caliber'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Brass',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('brand', models.CharField(max_length=100, verbose_name='brand')),
|
||||
('caliber', models.CharField(max_length=20, verbose_name='caliber')),
|
||||
('primer_pocket', models.CharField(blank=True, choices=[('SP', 'Small Pistol'), ('LP', 'Large Pistol'), ('SR', 'Small Rifle'), ('LR', 'Large Rifle'), ('LRM', 'Large Rifle Magnum')], max_length=3, verbose_name='primer pocket')),
|
||||
('trim_length_mm', models.DecimalField(blank=True, decimal_places=2, max_digits=6, null=True, verbose_name='trim-to length (mm)')),
|
||||
('notes', models.TextField(blank=True, verbose_name='notes')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'brass',
|
||||
'verbose_name_plural': 'brass',
|
||||
'ordering': ['brand', 'caliber'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Bullet',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('brand', models.CharField(max_length=100, verbose_name='brand')),
|
||||
('model_name', models.CharField(max_length=150, verbose_name='model name')),
|
||||
('weight_gr', models.DecimalField(decimal_places=1, max_digits=6, verbose_name='weight (gr)')),
|
||||
('bullet_type', models.CharField(choices=[('FMJ', 'Full Metal Jacket'), ('HP', 'Hollow Point'), ('BTHP', 'Boat Tail Hollow Point'), ('SP', 'Soft Point'), ('HPBT', 'Hollow Point Boat Tail'), ('SMK', 'Sierra MatchKing'), ('A_TIP', 'Hornady A-Tip'), ('MONO', 'Monolithic / Solid')], max_length=5, verbose_name='bullet type')),
|
||||
('diameter_mm', models.DecimalField(blank=True, decimal_places=3, max_digits=5, null=True, verbose_name='diameter (mm)')),
|
||||
('length_mm', models.DecimalField(blank=True, decimal_places=2, max_digits=5, null=True, verbose_name='length (mm)')),
|
||||
('bc_g1', models.DecimalField(blank=True, decimal_places=4, max_digits=5, null=True, verbose_name='BC (G1)')),
|
||||
('bc_g7', models.DecimalField(blank=True, decimal_places=4, max_digits=5, null=True, verbose_name='BC (G7)')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'bullet',
|
||||
'verbose_name_plural': 'bullets',
|
||||
'ordering': ['brand', 'model_name', 'weight_gr'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Powder',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('brand', models.CharField(max_length=100, verbose_name='brand')),
|
||||
('name', models.CharField(max_length=100, verbose_name='name')),
|
||||
('powder_type', models.CharField(blank=True, choices=[('BALL', 'Ball / Spherical'), ('EXTRUDED', 'Extruded / Stick'), ('FLAKE', 'Flake')], max_length=10, verbose_name='powder type')),
|
||||
('burn_rate_index', models.PositiveSmallIntegerField(blank=True, help_text='Lower = faster burning. Used for relative ordering only.', null=True, verbose_name='burn rate index')),
|
||||
('notes', models.TextField(blank=True, verbose_name='notes')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'powder',
|
||||
'verbose_name_plural': 'powders',
|
||||
'ordering': ['burn_rate_index', 'brand', 'name'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Primer',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('brand', models.CharField(max_length=100, verbose_name='brand')),
|
||||
('name', models.CharField(max_length=100, verbose_name='name')),
|
||||
('size', models.CharField(choices=[('SP', 'Small Pistol'), ('LP', 'Large Pistol'), ('SR', 'Small Rifle'), ('LR', 'Large Rifle'), ('LRM', 'Large Rifle Magnum')], max_length=3, verbose_name='size')),
|
||||
('notes', models.TextField(blank=True, verbose_name='notes')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'primer',
|
||||
'verbose_name_plural': 'primers',
|
||||
'ordering': ['brand', 'name'],
|
||||
},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='bipod',
|
||||
options={'verbose_name': 'bipod', 'verbose_name_plural': 'bipods'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='firearm',
|
||||
options={'verbose_name': 'firearm', 'verbose_name_plural': 'firearms'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='gear',
|
||||
options={'ordering': ['brand', 'model_name'], 'verbose_name': 'gear', 'verbose_name_plural': 'gears'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='magazine',
|
||||
options={'verbose_name': 'magazine', 'verbose_name_plural': 'magazines'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='rig',
|
||||
options={'ordering': ['-created_at'], 'verbose_name': 'rig', 'verbose_name_plural': 'rigs'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='rigitem',
|
||||
options={'verbose_name': 'rig item', 'verbose_name_plural': 'rig items'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='scope',
|
||||
options={'verbose_name': 'scope', 'verbose_name_plural': 'scopes'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='suppressor',
|
||||
options={'verbose_name': 'suppressor', 'verbose_name_plural': 'suppressors'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='usergear',
|
||||
options={'ordering': ['-added_at'], 'verbose_name': 'owned gear', 'verbose_name_plural': 'owned gears'},
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='bipod',
|
||||
name='attachment_type',
|
||||
field=models.CharField(blank=True, choices=[('PICATINNY', 'Picatinny Rail'), ('SLING_STUD', 'Sling Stud'), ('ARCA_SWISS', 'Arca-Swiss'), ('M_LOK', 'M-LOK'), ('KEYMOD', 'KeyMod')], max_length=20, verbose_name='attachment type'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='bipod',
|
||||
name='max_height_mm',
|
||||
field=models.DecimalField(blank=True, decimal_places=1, max_digits=6, null=True, verbose_name='max height (mm)'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='bipod',
|
||||
name='min_height_mm',
|
||||
field=models.DecimalField(blank=True, decimal_places=1, max_digits=6, null=True, verbose_name='min height (mm)'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='firearm',
|
||||
name='action',
|
||||
field=models.CharField(choices=[('BOLT', 'Bolt Action'), ('SEMI_AUTO', 'Semi-Automatic'), ('PUMP', 'Pump Action'), ('LEVER', 'Lever Action'), ('BREAK', 'Break Action'), ('FULL_AUTO', 'Full Automatic')], max_length=10, verbose_name='action'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='firearm',
|
||||
name='barrel_length_mm',
|
||||
field=models.DecimalField(blank=True, decimal_places=1, max_digits=6, null=True, verbose_name='barrel length (mm)'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='firearm',
|
||||
name='caliber',
|
||||
field=models.CharField(max_length=20, verbose_name='caliber'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='firearm',
|
||||
name='firearm_type',
|
||||
field=models.CharField(choices=[('RIFLE', 'Rifle'), ('PISTOL', 'Pistol'), ('SHOTGUN', 'Shotgun'), ('REVOLVER', 'Revolver'), ('CARBINE', 'Carbine')], max_length=10, verbose_name='firearm type'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='firearm',
|
||||
name='magazine_capacity',
|
||||
field=models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='magazine capacity'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='gear',
|
||||
name='brand',
|
||||
field=models.CharField(max_length=100, verbose_name='brand'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='gear',
|
||||
name='created_at',
|
||||
field=models.DateTimeField(auto_now_add=True, verbose_name='created at'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='gear',
|
||||
name='description',
|
||||
field=models.TextField(blank=True, verbose_name='description'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='gear',
|
||||
name='gear_type',
|
||||
field=models.CharField(choices=[('FIREARM', 'Firearm'), ('SCOPE', 'Scope'), ('SUPPRESSOR', 'Suppressor'), ('BIPOD', 'Bipod'), ('MAGAZINE', 'Magazine')], editable=False, max_length=20, verbose_name='gear type'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='gear',
|
||||
name='model_name',
|
||||
field=models.CharField(max_length=150, verbose_name='model name'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='gear',
|
||||
name='reviewed_at',
|
||||
field=models.DateTimeField(blank=True, null=True, verbose_name='reviewed at'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='gear',
|
||||
name='reviewed_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='reviewed_gears', to=settings.AUTH_USER_MODEL, verbose_name='reviewed by'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='gear',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('PENDING', 'Pending Verification'), ('VERIFIED', 'Verified'), ('REJECTED', 'Rejected')], default='PENDING', max_length=10, verbose_name='status'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='gear',
|
||||
name='submitted_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='submitted_gears', to=settings.AUTH_USER_MODEL, verbose_name='submitted by'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='gear',
|
||||
name='updated_at',
|
||||
field=models.DateTimeField(auto_now=True, verbose_name='updated at'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='magazine',
|
||||
name='caliber',
|
||||
field=models.CharField(max_length=20, verbose_name='caliber'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='magazine',
|
||||
name='capacity',
|
||||
field=models.PositiveSmallIntegerField(verbose_name='capacity'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='rig',
|
||||
name='created_at',
|
||||
field=models.DateTimeField(auto_now_add=True, verbose_name='created at'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='rig',
|
||||
name='description',
|
||||
field=models.TextField(blank=True, verbose_name='description'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='rig',
|
||||
name='items',
|
||||
field=models.ManyToManyField(related_name='rigs', through='gears.RigItem', to='gears.usergear', verbose_name='items'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='rig',
|
||||
name='name',
|
||||
field=models.CharField(max_length=100, verbose_name='name'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='rig',
|
||||
name='updated_at',
|
||||
field=models.DateTimeField(auto_now=True, verbose_name='updated at'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='rig',
|
||||
name='user',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='rigs', to=settings.AUTH_USER_MODEL, verbose_name='user'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='rigitem',
|
||||
name='rig',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='rig_items', to='gears.rig', verbose_name='rig'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='rigitem',
|
||||
name='role',
|
||||
field=models.CharField(choices=[('PRIMARY', 'Primary Firearm'), ('OPTIC', 'Optic / Scope'), ('SUPPRESSOR', 'Suppressor'), ('BIPOD', 'Bipod'), ('MAGAZINE', 'Magazine'), ('OTHER', 'Other Accessory')], default='OTHER', max_length=20, verbose_name='role'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='rigitem',
|
||||
name='user_gear',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='rig_items', to='gears.usergear', verbose_name='gear'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='scope',
|
||||
name='magnification_max',
|
||||
field=models.DecimalField(decimal_places=1, max_digits=5, verbose_name='max magnification'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='scope',
|
||||
name='magnification_min',
|
||||
field=models.DecimalField(decimal_places=1, max_digits=5, verbose_name='min magnification'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='scope',
|
||||
name='objective_diameter_mm',
|
||||
field=models.DecimalField(decimal_places=1, max_digits=5, verbose_name='objective diameter (mm)'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='scope',
|
||||
name='reticle_type',
|
||||
field=models.CharField(blank=True, choices=[('DUPLEX', 'Duplex'), ('MILDOT', 'Mil-Dot'), ('BDC', 'BDC'), ('ILLUMINATED', 'Illuminated'), ('ETCHED', 'Etched Glass')], max_length=20, verbose_name='reticle type'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='scope',
|
||||
name='tube_diameter_mm',
|
||||
field=models.DecimalField(decimal_places=1, default=30, max_digits=5, verbose_name='tube diameter (mm)'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='suppressor',
|
||||
name='length_mm',
|
||||
field=models.DecimalField(blank=True, decimal_places=1, max_digits=6, null=True, verbose_name='length (mm)'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='suppressor',
|
||||
name='max_caliber',
|
||||
field=models.CharField(max_length=20, verbose_name='max caliber'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='suppressor',
|
||||
name='thread_pitch',
|
||||
field=models.CharField(blank=True, max_length=20, verbose_name='thread pitch'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='suppressor',
|
||||
name='weight_g',
|
||||
field=models.DecimalField(blank=True, decimal_places=1, max_digits=6, null=True, verbose_name='weight (g)'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='usergear',
|
||||
name='added_at',
|
||||
field=models.DateTimeField(auto_now_add=True, verbose_name='added at'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='usergear',
|
||||
name='gear',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='user_instances', to='gears.gear', verbose_name='gear'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='usergear',
|
||||
name='nickname',
|
||||
field=models.CharField(blank=True, max_length=100, verbose_name='nickname'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='usergear',
|
||||
name='notes',
|
||||
field=models.TextField(blank=True, verbose_name='notes'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='usergear',
|
||||
name='purchase_date',
|
||||
field=models.DateField(blank=True, null=True, verbose_name='purchase date'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='usergear',
|
||||
name='serial_number',
|
||||
field=models.CharField(blank=True, max_length=100, verbose_name='serial number'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='usergear',
|
||||
name='user',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='inventory', to=settings.AUTH_USER_MODEL, verbose_name='user'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ReloadRecipe',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=150, verbose_name='name')),
|
||||
('caliber', models.CharField(max_length=20, verbose_name='caliber')),
|
||||
('notes', models.TextField(blank=True, verbose_name='notes')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='created at')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='updated at')),
|
||||
('brass', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='recipes', to='gears.brass', verbose_name='brass')),
|
||||
('bullet', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='recipes', to='gears.bullet', verbose_name='bullet')),
|
||||
('primer', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='recipes', to='gears.primer', verbose_name='primer')),
|
||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reload_recipes', to=settings.AUTH_USER_MODEL, verbose_name='user')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'reload recipe',
|
||||
'verbose_name_plural': 'reload recipes',
|
||||
'ordering': ['-created_at'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ReloadedAmmoBatch',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('powder_charge_gr', models.DecimalField(decimal_places=2, max_digits=5, verbose_name='powder charge (gr)')),
|
||||
('quantity', models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='quantity loaded')),
|
||||
('oal_mm', models.DecimalField(blank=True, decimal_places=2, max_digits=6, null=True, verbose_name='overall length (mm)')),
|
||||
('coal_mm', models.DecimalField(blank=True, decimal_places=2, max_digits=6, null=True, verbose_name='cartridge overall length to ogive (mm)')),
|
||||
('crimp', models.CharField(choices=[('NONE', 'No Crimp'), ('TAPER', 'Taper Crimp'), ('ROLL', 'Roll Crimp')], default='NONE', max_length=6, verbose_name='crimp')),
|
||||
('case_prep_notes', models.TextField(blank=True, verbose_name='case prep notes')),
|
||||
('notes', models.TextField(blank=True, verbose_name='notes')),
|
||||
('loaded_at', models.DateField(blank=True, null=True, verbose_name='loaded at')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='created at')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='updated at')),
|
||||
('powder', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='batches', to='gears.powder', verbose_name='powder')),
|
||||
('recipe', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='batches', to='gears.reloadrecipe', verbose_name='recipe')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'reloaded ammo batch',
|
||||
'verbose_name_plural': 'reloaded ammo batches',
|
||||
'ordering': ['recipe', 'powder_charge_gr'],
|
||||
},
|
||||
),
|
||||
migrations.AddConstraint(
|
||||
model_name='primer',
|
||||
constraint=models.UniqueConstraint(fields=('brand', 'name'), name='unique_primer_brand_name'),
|
||||
),
|
||||
migrations.AddConstraint(
|
||||
model_name='powder',
|
||||
constraint=models.UniqueConstraint(fields=('brand', 'name'), name='unique_powder_brand_name'),
|
||||
),
|
||||
migrations.AddConstraint(
|
||||
model_name='bullet',
|
||||
constraint=models.UniqueConstraint(fields=('brand', 'model_name', 'weight_gr'), name='unique_bullet_brand_model_weight'),
|
||||
),
|
||||
migrations.AddConstraint(
|
||||
model_name='brass',
|
||||
constraint=models.UniqueConstraint(fields=('brand', 'caliber'), name='unique_brass_brand_caliber'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ammo',
|
||||
name='reviewed_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='reviewed_ammo', to=settings.AUTH_USER_MODEL, verbose_name='reviewed by'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ammo',
|
||||
name='submitted_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='submitted_ammo', to=settings.AUTH_USER_MODEL, verbose_name='submitted by'),
|
||||
),
|
||||
migrations.AddConstraint(
|
||||
model_name='reloadrecipe',
|
||||
constraint=models.UniqueConstraint(fields=('user', 'name'), name='unique_recipe_name_per_user'),
|
||||
),
|
||||
migrations.AddConstraint(
|
||||
model_name='reloadedammobatch',
|
||||
constraint=models.UniqueConstraint(fields=('recipe', 'powder', 'powder_charge_gr'), name='unique_batch_charge_per_recipe_powder'),
|
||||
),
|
||||
migrations.AddConstraint(
|
||||
model_name='ammo',
|
||||
constraint=models.UniqueConstraint(fields=('brand', 'name', 'caliber'), name='unique_ammo_brand_name_caliber'),
|
||||
),
|
||||
]
|
||||
1035
apps/gears/migrations/0004_catalog_initial_data.py
Normal file
1035
apps/gears/migrations/0004_catalog_initial_data.py
Normal file
File diff suppressed because it is too large
Load Diff
16
apps/gears/migrations/0005_rig_is_public.py
Normal file
16
apps/gears/migrations/0005_rig_is_public.py
Normal file
@@ -0,0 +1,16 @@
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gears', '0004_catalog_initial_data'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='rig',
|
||||
name='is_public',
|
||||
field=models.BooleanField(default=False, verbose_name='public'),
|
||||
),
|
||||
]
|
||||
31
apps/gears/migrations/0007_scope_optics.py
Normal file
31
apps/gears/migrations/0007_scope_optics.py
Normal file
@@ -0,0 +1,31 @@
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gears', 'gears_0006_component_status'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='scope',
|
||||
name='adjustment_unit',
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
choices=[('MOA', 'MOA (Minute of Angle)'), ('MRAD', 'MRAD (Milliradian)')],
|
||||
max_length=4,
|
||||
verbose_name='adjustment unit',
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='scope',
|
||||
name='focal_plane',
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
choices=[('FFP', 'First Focal Plane (FFP)'), ('SFP', 'Second Focal Plane (SFP)')],
|
||||
max_length=3,
|
||||
verbose_name='focal plane',
|
||||
),
|
||||
),
|
||||
]
|
||||
428
apps/gears/migrations/0008_catalog_enrichment.py
Normal file
428
apps/gears/migrations/0008_catalog_enrichment.py
Normal file
@@ -0,0 +1,428 @@
|
||||
"""
|
||||
Data migration: enrich the public catalog with additional firearms (pistols,
|
||||
semi-auto rifles, rimfire), scopes (with adjustment_unit/focal_plane),
|
||||
suppressors, bipods and magazines.
|
||||
|
||||
All items use get_or_create() to be idempotent.
|
||||
"""
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
def _get(apps, model_name):
|
||||
return apps.get_model('gears', model_name)
|
||||
|
||||
|
||||
def add_firearms(apps, schema_editor):
|
||||
Firearm = _get(apps, 'Firearm')
|
||||
V = 'VERIFIED'
|
||||
|
||||
items = [
|
||||
# ── Pistols ─────────────────────────────────────────────────────────
|
||||
dict(brand='Glock', model_name='G17 Gen5', gear_type='FIREARM',
|
||||
firearm_type='PISTOL', caliber='9mm Luger', action='SEMI-AUTO',
|
||||
barrel_length_mm=114, magazine_capacity=17, status=V),
|
||||
dict(brand='Glock', model_name='G19 Gen5', gear_type='FIREARM',
|
||||
firearm_type='PISTOL', caliber='9mm Luger', action='SEMI-AUTO',
|
||||
barrel_length_mm=102, magazine_capacity=15, status=V),
|
||||
dict(brand='Glock', model_name='G34 Gen5 MOS', gear_type='FIREARM',
|
||||
firearm_type='PISTOL', caliber='9mm Luger', action='SEMI-AUTO',
|
||||
barrel_length_mm=135, magazine_capacity=17, status=V),
|
||||
dict(brand='Glock', model_name='G19X', gear_type='FIREARM',
|
||||
firearm_type='PISTOL', caliber='9mm Luger', action='SEMI-AUTO',
|
||||
barrel_length_mm=102, magazine_capacity=17, status=V),
|
||||
dict(brand='Glock', model_name='G45', gear_type='FIREARM',
|
||||
firearm_type='PISTOL', caliber='9mm Luger', action='SEMI-AUTO',
|
||||
barrel_length_mm=114, magazine_capacity=17, status=V),
|
||||
dict(brand='SIG Sauer', model_name='P320 M17', gear_type='FIREARM',
|
||||
firearm_type='PISTOL', caliber='9mm Luger', action='SEMI-AUTO',
|
||||
barrel_length_mm=112, magazine_capacity=17, status=V),
|
||||
dict(brand='SIG Sauer', model_name='P320 X5 Legion', gear_type='FIREARM',
|
||||
firearm_type='PISTOL', caliber='9mm Luger', action='SEMI-AUTO',
|
||||
barrel_length_mm=127, magazine_capacity=21, status=V),
|
||||
dict(brand='SIG Sauer', model_name='P226', gear_type='FIREARM',
|
||||
firearm_type='PISTOL', caliber='9mm Luger', action='SEMI-AUTO',
|
||||
barrel_length_mm=112, magazine_capacity=15, status=V),
|
||||
dict(brand='SIG Sauer', model_name='P226 Legion', gear_type='FIREARM',
|
||||
firearm_type='PISTOL', caliber='9mm Luger', action='SEMI-AUTO',
|
||||
barrel_length_mm=112, magazine_capacity=15, status=V),
|
||||
dict(brand='CZ', model_name='Shadow 2', gear_type='FIREARM',
|
||||
firearm_type='PISTOL', caliber='9mm Luger', action='SEMI-AUTO',
|
||||
barrel_length_mm=120, magazine_capacity=17, status=V),
|
||||
dict(brand='CZ', model_name='SP-01 Tactical', gear_type='FIREARM',
|
||||
firearm_type='PISTOL', caliber='9mm Luger', action='SEMI-AUTO',
|
||||
barrel_length_mm=119, magazine_capacity=18, status=V),
|
||||
dict(brand='Beretta', model_name='92FS', gear_type='FIREARM',
|
||||
firearm_type='PISTOL', caliber='9mm Luger', action='SEMI-AUTO',
|
||||
barrel_length_mm=125, magazine_capacity=15, status=V),
|
||||
dict(brand='Beretta', model_name='APX A1', gear_type='FIREARM',
|
||||
firearm_type='PISTOL', caliber='9mm Luger', action='SEMI-AUTO',
|
||||
barrel_length_mm=108, magazine_capacity=15, status=V),
|
||||
dict(brand='Smith & Wesson', model_name='M&P 2.0 5" Pro', gear_type='FIREARM',
|
||||
firearm_type='PISTOL', caliber='9mm Luger', action='SEMI-AUTO',
|
||||
barrel_length_mm=127, magazine_capacity=17, status=V),
|
||||
dict(brand='Smith & Wesson', model_name='M&P 2.0 Compact 4"', gear_type='FIREARM',
|
||||
firearm_type='PISTOL', caliber='9mm Luger', action='SEMI-AUTO',
|
||||
barrel_length_mm=102, magazine_capacity=15, status=V),
|
||||
dict(brand='HK', model_name='VP9', gear_type='FIREARM',
|
||||
firearm_type='PISTOL', caliber='9mm Luger', action='SEMI-AUTO',
|
||||
barrel_length_mm=108, magazine_capacity=15, status=V),
|
||||
dict(brand='HK', model_name='USP Tactical 9mm', gear_type='FIREARM',
|
||||
firearm_type='PISTOL', caliber='9mm Luger', action='SEMI-AUTO',
|
||||
barrel_length_mm=123, magazine_capacity=15, status=V),
|
||||
dict(brand='Walther', model_name='Q5 Match Steel Frame', gear_type='FIREARM',
|
||||
firearm_type='PISTOL', caliber='9mm Luger', action='SEMI-AUTO',
|
||||
barrel_length_mm=127, magazine_capacity=15, status=V),
|
||||
dict(brand='Walther', model_name='PPQ M2 5"', gear_type='FIREARM',
|
||||
firearm_type='PISTOL', caliber='9mm Luger', action='SEMI-AUTO',
|
||||
barrel_length_mm=127, magazine_capacity=15, status=V),
|
||||
dict(brand='FN', model_name='FN 509 Tactical', gear_type='FIREARM',
|
||||
firearm_type='PISTOL', caliber='9mm Luger', action='SEMI-AUTO',
|
||||
barrel_length_mm=121, magazine_capacity=17, status=V),
|
||||
dict(brand='Canik', model_name='TP9SFx', gear_type='FIREARM',
|
||||
firearm_type='PISTOL', caliber='9mm Luger', action='SEMI-AUTO',
|
||||
barrel_length_mm=127, magazine_capacity=20, status=V),
|
||||
dict(brand='Springfield Armory', model_name='XD-M Elite 5.25" OSP', gear_type='FIREARM',
|
||||
firearm_type='PISTOL', caliber='9mm Luger', action='SEMI-AUTO',
|
||||
barrel_length_mm=133, magazine_capacity=22, status=V),
|
||||
# ── Semi-auto rifles ─────────────────────────────────────────────────
|
||||
dict(brand='HK', model_name='HK416 A5 14.5"', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='5.56x45mm NATO', action='SEMI-AUTO',
|
||||
barrel_length_mm=368, magazine_capacity=30, status=V),
|
||||
dict(brand='HK', model_name='HK417 A2 16"', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='7.62x51mm NATO', action='SEMI-AUTO',
|
||||
barrel_length_mm=406, magazine_capacity=20, status=V),
|
||||
dict(brand='SIG Sauer', model_name='MCX Spear 16"', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='6.8x51mm', action='SEMI-AUTO',
|
||||
barrel_length_mm=406, magazine_capacity=20, status=V),
|
||||
dict(brand='FN', model_name='SCAR 16S', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='5.56x45mm NATO', action='SEMI-AUTO',
|
||||
barrel_length_mm=406, magazine_capacity=30, status=V),
|
||||
dict(brand='FN', model_name='SCAR 17S', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='7.62x51mm NATO', action='SEMI-AUTO',
|
||||
barrel_length_mm=406, magazine_capacity=20, status=V),
|
||||
dict(brand='Daniel Defense', model_name='DDM4 V7 16"', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='5.56x45mm NATO', action='SEMI-AUTO',
|
||||
barrel_length_mm=406, magazine_capacity=30, status=V),
|
||||
dict(brand='Bravo Company Mfg', model_name='Recce-16 MCMR', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='5.56x45mm NATO', action='SEMI-AUTO',
|
||||
barrel_length_mm=406, magazine_capacity=30, status=V),
|
||||
dict(brand='JP Enterprises', model_name='JP-5 16" PCC', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='9mm Luger', action='SEMI-AUTO',
|
||||
barrel_length_mm=406, magazine_capacity=17, status=V),
|
||||
dict(brand='SIG Sauer', model_name='MCX Rattler 5.5"', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='300 Blackout', action='SEMI-AUTO',
|
||||
barrel_length_mm=140, magazine_capacity=30, status=V),
|
||||
# ── Rimfire ──────────────────────────────────────────────────────────
|
||||
dict(brand='Ruger', model_name='10/22 Carbine', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='.22 LR', action='SEMI-AUTO',
|
||||
barrel_length_mm=470, magazine_capacity=10, status=V),
|
||||
dict(brand='Ruger', model_name='American Rimfire .22 LR', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='.22 LR', action='BOLT',
|
||||
barrel_length_mm=559, magazine_capacity=10, status=V),
|
||||
dict(brand='CZ', model_name='457 American .22 LR', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='.22 LR', action='BOLT',
|
||||
barrel_length_mm=508, magazine_capacity=5, status=V),
|
||||
dict(brand='CZ', model_name='457 Varmint .22 LR', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='.22 LR', action='BOLT',
|
||||
barrel_length_mm=610, magazine_capacity=5, status=V),
|
||||
dict(brand='Anschütz', model_name='1710 D HB .22 LR', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='.22 LR', action='BOLT',
|
||||
barrel_length_mm=660, magazine_capacity=5, status=V),
|
||||
dict(brand='Anschütz', model_name='2013 Supermatch .22 LR', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='.22 LR', action='BOLT',
|
||||
barrel_length_mm=690, magazine_capacity=1, status=V),
|
||||
# ── Additional bolt-action rifles ────────────────────────────────────
|
||||
dict(brand='CZ', model_name='600 Alpha .308', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
|
||||
barrel_length_mm=560, status=V),
|
||||
dict(brand='CZ', model_name='600 Range .308', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
|
||||
barrel_length_mm=660, status=V),
|
||||
dict(brand='Christensen Arms', model_name='Modern Precision Rifle 6.5CM', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='6.5 Creedmoor', action='BOLT',
|
||||
barrel_length_mm=610, status=V),
|
||||
dict(brand='Christensen Arms', model_name='Modern Precision Rifle .308', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
|
||||
barrel_length_mm=610, status=V),
|
||||
dict(brand='Proof Research', model_name='Glacier Ti 6.5CM', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='6.5 Creedmoor', action='BOLT',
|
||||
barrel_length_mm=559, status=V),
|
||||
dict(brand='Winchester', model_name='XPR .308', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
|
||||
barrel_length_mm=610, status=V),
|
||||
dict(brand='Winchester', model_name='XPR 6.5CM', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='6.5 Creedmoor', action='BOLT',
|
||||
barrel_length_mm=610, status=V),
|
||||
dict(brand='Mossberg', model_name='MVP Precision .308', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
|
||||
barrel_length_mm=660, status=V),
|
||||
dict(brand='Desert Tech', model_name='SRS A2 .308', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
|
||||
barrel_length_mm=610, status=V),
|
||||
dict(brand='Desert Tech', model_name='SRS A2 6.5CM', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='6.5 Creedmoor', action='BOLT',
|
||||
barrel_length_mm=610, status=V),
|
||||
dict(brand='Victrix Armaments', model_name='Scorpio T 6.5CM', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='6.5 Creedmoor', action='BOLT',
|
||||
barrel_length_mm=660, status=V),
|
||||
dict(brand='Victrix Armaments', model_name='Venus .308', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
|
||||
barrel_length_mm=660, status=V),
|
||||
dict(brand='Bergara', model_name='B-14 Squared Crest 6.5CM', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='6.5 Creedmoor', action='BOLT',
|
||||
barrel_length_mm=559, status=V),
|
||||
dict(brand='Bergara', model_name='Premier HMR Pro 6.5PRC', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='6.5 PRC', action='BOLT',
|
||||
barrel_length_mm=610, status=V),
|
||||
dict(brand='Tikka', model_name='T3x UPR 6.5CM', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='6.5 Creedmoor', action='BOLT',
|
||||
barrel_length_mm=610, status=V),
|
||||
dict(brand='Sako', model_name='90 Adventure .308', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
|
||||
barrel_length_mm=572, status=V),
|
||||
dict(brand='Sako', model_name='90 Peak 6.5CM', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='6.5 Creedmoor', action='BOLT',
|
||||
barrel_length_mm=560, status=V),
|
||||
dict(brand='Accuracy International', model_name='AX308 .308', gear_type='FIREARM',
|
||||
firearm_type='RIFLE', caliber='.308 Win', action='BOLT',
|
||||
barrel_length_mm=660, status=V),
|
||||
]
|
||||
|
||||
for data in items:
|
||||
Firearm.objects.get_or_create(
|
||||
brand=data['brand'],
|
||||
model_name=data['model_name'],
|
||||
defaults=data,
|
||||
)
|
||||
|
||||
|
||||
def add_scopes(apps, schema_editor):
|
||||
Scope = _get(apps, 'Scope')
|
||||
V = 'VERIFIED'
|
||||
|
||||
items = [
|
||||
dict(brand='Athlon', model_name='Argos BTR 6-24x50', gear_type='SCOPE',
|
||||
magnification_min=6, magnification_max=24, objective_diameter_mm=50,
|
||||
tube_diameter_mm=30, reticle_type='MILDOT',
|
||||
adjustment_unit='MRAD', focal_plane='FFP', status=V),
|
||||
dict(brand='Athlon', model_name='Cronus BTR 4.5-29x56', gear_type='SCOPE',
|
||||
magnification_min=4, magnification_max=29, objective_diameter_mm=56,
|
||||
tube_diameter_mm=34, reticle_type='MILDOT',
|
||||
adjustment_unit='MRAD', focal_plane='FFP', status=V),
|
||||
dict(brand='Athlon', model_name='Ares BTR 4.5-27x50 FFP', gear_type='SCOPE',
|
||||
magnification_min=4, magnification_max=27, objective_diameter_mm=50,
|
||||
tube_diameter_mm=30, reticle_type='MILDOT',
|
||||
adjustment_unit='MRAD', focal_plane='FFP', status=V),
|
||||
dict(brand='Primary Arms', model_name='PLx 6-30x56 FFP', gear_type='SCOPE',
|
||||
magnification_min=6, magnification_max=30, objective_diameter_mm=56,
|
||||
tube_diameter_mm=34, reticle_type='MILDOT',
|
||||
adjustment_unit='MRAD', focal_plane='FFP', status=V),
|
||||
dict(brand='Primary Arms', model_name='SLx 4-16x44 FFP', gear_type='SCOPE',
|
||||
magnification_min=4, magnification_max=16, objective_diameter_mm=44,
|
||||
tube_diameter_mm=30, reticle_type='MILDOT',
|
||||
adjustment_unit='MRAD', focal_plane='FFP', status=V),
|
||||
dict(brand='Hawke', model_name='Sidewinder 30 6-24x50 FFP', gear_type='SCOPE',
|
||||
magnification_min=6, magnification_max=24, objective_diameter_mm=50,
|
||||
tube_diameter_mm=30, reticle_type='MILDOT',
|
||||
adjustment_unit='MOA', focal_plane='FFP', status=V),
|
||||
dict(brand='Delta Optical', model_name='Stryker HD 4.5-30x56 FFP', gear_type='SCOPE',
|
||||
magnification_min=4, magnification_max=30, objective_diameter_mm=56,
|
||||
tube_diameter_mm=34, reticle_type='MILDOT',
|
||||
adjustment_unit='MRAD', focal_plane='FFP', status=V),
|
||||
dict(brand='Kahles', model_name='K525i 5-25x56 FFP', gear_type='SCOPE',
|
||||
magnification_min=5, magnification_max=25, objective_diameter_mm=56,
|
||||
tube_diameter_mm=34, reticle_type='MILDOT',
|
||||
adjustment_unit='MRAD', focal_plane='FFP', status=V),
|
||||
dict(brand='March', model_name='FX 8-80x56 FFP', gear_type='SCOPE',
|
||||
magnification_min=8, magnification_max=80, objective_diameter_mm=56,
|
||||
tube_diameter_mm=34, reticle_type='MILDOT',
|
||||
adjustment_unit='MRAD', focal_plane='FFP', status=V),
|
||||
dict(brand='March', model_name='Genesis 6-60x56 FFP', gear_type='SCOPE',
|
||||
magnification_min=6, magnification_max=60, objective_diameter_mm=56,
|
||||
tube_diameter_mm=34, reticle_type='MILDOT',
|
||||
adjustment_unit='MRAD', focal_plane='FFP', status=V),
|
||||
dict(brand='SIG Sauer', model_name='TANGO6T 1-6x24 FFP', gear_type='SCOPE',
|
||||
magnification_min=1, magnification_max=6, objective_diameter_mm=24,
|
||||
tube_diameter_mm=30, reticle_type='ILLUMINATED',
|
||||
adjustment_unit='MOA', focal_plane='FFP', status=V),
|
||||
dict(brand='SIG Sauer', model_name='TANGO4 4-16x44 FFP', gear_type='SCOPE',
|
||||
magnification_min=4, magnification_max=16, objective_diameter_mm=44,
|
||||
tube_diameter_mm=30, reticle_type='MILDOT',
|
||||
adjustment_unit='MOA', focal_plane='FFP', status=V),
|
||||
dict(brand='Leupold', model_name='VX-5HD 3-15x44 CDS-TZL3', gear_type='SCOPE',
|
||||
magnification_min=3, magnification_max=15, objective_diameter_mm=44,
|
||||
tube_diameter_mm=30, reticle_type='DUPLEX',
|
||||
adjustment_unit='MOA', focal_plane='SFP', status=V),
|
||||
dict(brand='Leupold', model_name='Mark 5HD 5-25x56 M5C3', gear_type='SCOPE',
|
||||
magnification_min=5, magnification_max=25, objective_diameter_mm=56,
|
||||
tube_diameter_mm=35, reticle_type='MILDOT',
|
||||
adjustment_unit='MRAD', focal_plane='FFP', status=V),
|
||||
dict(brand='Burris', model_name='XTR III 3.3-18x50 FFP', gear_type='SCOPE',
|
||||
magnification_min=3, magnification_max=18, objective_diameter_mm=50,
|
||||
tube_diameter_mm=34, reticle_type='MILDOT',
|
||||
adjustment_unit='MRAD', focal_plane='FFP', status=V),
|
||||
dict(brand='US Optics', model_name='B-25 5-25x52 FFP', gear_type='SCOPE',
|
||||
magnification_min=5, magnification_max=25, objective_diameter_mm=52,
|
||||
tube_diameter_mm=34, reticle_type='MILDOT',
|
||||
adjustment_unit='MRAD', focal_plane='FFP', status=V),
|
||||
dict(brand='IOR Valdada', model_name='Terminator 3-18x50 FFP', gear_type='SCOPE',
|
||||
magnification_min=3, magnification_max=18, objective_diameter_mm=50,
|
||||
tube_diameter_mm=30, reticle_type='MILDOT',
|
||||
adjustment_unit='MRAD', focal_plane='FFP', status=V),
|
||||
dict(brand='Vortex', model_name='Strike Eagle 5-25x56', gear_type='SCOPE',
|
||||
magnification_min=5, magnification_max=25, objective_diameter_mm=56,
|
||||
tube_diameter_mm=34, reticle_type='ILLUMINATED',
|
||||
adjustment_unit='MOA', focal_plane='FFP', status=V),
|
||||
dict(brand='Vortex', model_name='Diamondback Tactical 6-24x50', gear_type='SCOPE',
|
||||
magnification_min=6, magnification_max=24, objective_diameter_mm=50,
|
||||
tube_diameter_mm=30, reticle_type='ETCHED',
|
||||
adjustment_unit='MOA', focal_plane='FFP', status=V),
|
||||
dict(brand='Nightforce', model_name='ATACR 7-35x56 F1', gear_type='SCOPE',
|
||||
magnification_min=7, magnification_max=35, objective_diameter_mm=56,
|
||||
tube_diameter_mm=34, reticle_type='MILDOT',
|
||||
adjustment_unit='MRAD', focal_plane='FFP', status=V),
|
||||
dict(brand='Nightforce', model_name='NXS 5.5-22x56 F1', gear_type='SCOPE',
|
||||
magnification_min=5, magnification_max=22, objective_diameter_mm=56,
|
||||
tube_diameter_mm=30, reticle_type='MILDOT',
|
||||
adjustment_unit='MRAD', focal_plane='FFP', status=V),
|
||||
]
|
||||
|
||||
for data in items:
|
||||
Scope.objects.get_or_create(
|
||||
brand=data['brand'],
|
||||
model_name=data['model_name'],
|
||||
defaults=data,
|
||||
)
|
||||
|
||||
|
||||
def add_suppressors(apps, schema_editor):
|
||||
Suppressor = _get(apps, 'Suppressor')
|
||||
V = 'VERIFIED'
|
||||
|
||||
items = [
|
||||
dict(brand='OSS', model_name='HX-QD 556', gear_type='SUPPRESSOR',
|
||||
max_caliber='5.56mm NATO', thread_pitch='1/2-28',
|
||||
length_mm=170, weight_g=340, status=V),
|
||||
dict(brand='Griffin Armament', model_name='Resistance 46M', gear_type='SUPPRESSOR',
|
||||
max_caliber='9mm Luger', thread_pitch='1/2-28',
|
||||
length_mm=190, weight_g=283, status=V),
|
||||
dict(brand='SureFire', model_name='SOCOM556-RC2', gear_type='SUPPRESSOR',
|
||||
max_caliber='5.56mm NATO', thread_pitch='1/2-28',
|
||||
length_mm=152, weight_g=454, status=V),
|
||||
dict(brand='AAC', model_name='SDN-6', gear_type='SUPPRESSOR',
|
||||
max_caliber='7.62mm NATO', thread_pitch='5/8-24',
|
||||
length_mm=185, weight_g=496, status=V),
|
||||
dict(brand='SilencerCo', model_name='Omega 9K', gear_type='SUPPRESSOR',
|
||||
max_caliber='9mm Luger', thread_pitch='1/2-28',
|
||||
length_mm=127, weight_g=340, status=V),
|
||||
dict(brand='Dead Air', model_name='Nomad-L', gear_type='SUPPRESSOR',
|
||||
max_caliber='7.62mm NATO', thread_pitch='5/8-24',
|
||||
length_mm=216, weight_g=510, status=V),
|
||||
dict(brand='Rugged', model_name='Obsidian 9', gear_type='SUPPRESSOR',
|
||||
max_caliber='9mm Luger', thread_pitch='1/2-28',
|
||||
length_mm=203, weight_g=425, status=V),
|
||||
dict(brand='Gemtech', model_name='G5-T 7.62', gear_type='SUPPRESSOR',
|
||||
max_caliber='7.62mm NATO', thread_pitch='5/8-24',
|
||||
length_mm=191, weight_g=510, status=V),
|
||||
dict(brand='B&T', model_name='Rotex-V 7.62', gear_type='SUPPRESSOR',
|
||||
max_caliber='7.62mm NATO', thread_pitch='5/8-24',
|
||||
length_mm=220, weight_g=640, status=V),
|
||||
]
|
||||
|
||||
for data in items:
|
||||
Suppressor.objects.get_or_create(
|
||||
brand=data['brand'],
|
||||
model_name=data['model_name'],
|
||||
defaults=data,
|
||||
)
|
||||
|
||||
|
||||
def add_bipods(apps, schema_editor):
|
||||
Bipod = _get(apps, 'Bipod')
|
||||
V = 'VERIFIED'
|
||||
|
||||
items = [
|
||||
dict(brand='Caldwell', model_name='XLA 9-13"', gear_type='BIPOD',
|
||||
min_height_mm=229, max_height_mm=330,
|
||||
attachment_type='Picatinny', status=V),
|
||||
dict(brand='RRS', model_name='SOAR B2 Arca', gear_type='BIPOD',
|
||||
min_height_mm=177, max_height_mm=330,
|
||||
attachment_type='Arca-Swiss/Picatinny', status=V),
|
||||
dict(brand='Trigger-Tech', model_name='Diamond Bipod', gear_type='BIPOD',
|
||||
min_height_mm=152, max_height_mm=280,
|
||||
attachment_type='Picatinny', status=V),
|
||||
dict(brand='Spartan Precision', model_name='Javelin Lite', gear_type='BIPOD',
|
||||
min_height_mm=178, max_height_mm=330,
|
||||
attachment_type='Sling stud/Picatinny', status=V),
|
||||
dict(brand='Fortmeier', model_name='H-POD', gear_type='BIPOD',
|
||||
min_height_mm=200, max_height_mm=380,
|
||||
attachment_type='Picatinny', status=V),
|
||||
]
|
||||
|
||||
for data in items:
|
||||
Bipod.objects.get_or_create(
|
||||
brand=data['brand'],
|
||||
model_name=data['model_name'],
|
||||
defaults=data,
|
||||
)
|
||||
|
||||
|
||||
def add_magazines(apps, schema_editor):
|
||||
Magazine = _get(apps, 'Magazine')
|
||||
V = 'VERIFIED'
|
||||
|
||||
items = [
|
||||
dict(brand='Glock', model_name='G17 Factory 17rd', gear_type='MAGAZINE',
|
||||
caliber='9mm Luger', capacity=17, status=V),
|
||||
dict(brand='Glock', model_name='G17 Factory 33rd', gear_type='MAGAZINE',
|
||||
caliber='9mm Luger', capacity=33, status=V),
|
||||
dict(brand='Glock', model_name='G19 Factory 15rd', gear_type='MAGAZINE',
|
||||
caliber='9mm Luger', capacity=15, status=V),
|
||||
dict(brand='SIG Sauer', model_name='P320 Factory 17rd', gear_type='MAGAZINE',
|
||||
caliber='9mm Luger', capacity=17, status=V),
|
||||
dict(brand='SIG Sauer', model_name='P320 Factory 21rd', gear_type='MAGAZINE',
|
||||
caliber='9mm Luger', capacity=21, status=V),
|
||||
dict(brand='CZ', model_name='Shadow 2 Factory 17rd', gear_type='MAGAZINE',
|
||||
caliber='9mm Luger', capacity=17, status=V),
|
||||
dict(brand='HK', model_name='VP9 Factory 15rd', gear_type='MAGAZINE',
|
||||
caliber='9mm Luger', capacity=15, status=V),
|
||||
dict(brand='Beretta', model_name='92FS Factory 15rd', gear_type='MAGAZINE',
|
||||
caliber='9mm Luger', capacity=15, status=V),
|
||||
dict(brand='Magpul', model_name='PMAG 10 AR/M4 Gen M3', gear_type='MAGAZINE',
|
||||
caliber='5.56x45mm NATO', capacity=10, status=V),
|
||||
dict(brand='Magpul', model_name='PMAG D-60 AR/M4', gear_type='MAGAZINE',
|
||||
caliber='5.56x45mm NATO', capacity=60, status=V),
|
||||
dict(brand='Ruger', model_name='BX-25 10/22', gear_type='MAGAZINE',
|
||||
caliber='.22 LR', capacity=25, status=V),
|
||||
dict(brand='Ruger', model_name='BX-1 10/22', gear_type='MAGAZINE',
|
||||
caliber='.22 LR', capacity=10, status=V),
|
||||
dict(brand='CZ', model_name='457 Factory 5rd', gear_type='MAGAZINE',
|
||||
caliber='.22 LR', capacity=5, status=V),
|
||||
dict(brand='CZ', model_name='457 Factory 10rd', gear_type='MAGAZINE',
|
||||
caliber='.22 LR', capacity=10, status=V),
|
||||
dict(brand='Magpul', model_name='PMAG 20 GL9 (Glock 17)', gear_type='MAGAZINE',
|
||||
caliber='9mm Luger', capacity=20, status=V),
|
||||
]
|
||||
|
||||
for data in items:
|
||||
Magazine.objects.get_or_create(
|
||||
brand=data['brand'],
|
||||
model_name=data['model_name'],
|
||||
caliber=data.get('caliber', ''),
|
||||
defaults=data,
|
||||
)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gears', '0007_scope_optics'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(add_firearms, migrations.RunPython.noop),
|
||||
migrations.RunPython(add_scopes, migrations.RunPython.noop),
|
||||
migrations.RunPython(add_suppressors, migrations.RunPython.noop),
|
||||
migrations.RunPython(add_bipods, migrations.RunPython.noop),
|
||||
migrations.RunPython(add_magazines, migrations.RunPython.noop),
|
||||
]
|
||||
@@ -0,0 +1,36 @@
|
||||
# Generated by Django 4.2.16 on 2026-03-25 08:38
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('gears', '0008_catalog_enrichment'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='brass',
|
||||
name='submitted_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='submitted_%(class)ss', to=settings.AUTH_USER_MODEL, verbose_name='submitted by'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='bullet',
|
||||
name='submitted_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='submitted_%(class)ss', to=settings.AUTH_USER_MODEL, verbose_name='submitted by'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='powder',
|
||||
name='submitted_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='submitted_%(class)ss', to=settings.AUTH_USER_MODEL, verbose_name='submitted by'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='primer',
|
||||
name='submitted_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='submitted_%(class)ss', to=settings.AUTH_USER_MODEL, verbose_name='submitted by'),
|
||||
),
|
||||
]
|
||||
20
apps/gears/migrations/0010_rig_photo.py
Normal file
20
apps/gears/migrations/0010_rig_photo.py
Normal file
@@ -0,0 +1,20 @@
|
||||
# Generated by Django 4.2.16 on 2026-03-25 10:15
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('photos', '0001_initial'),
|
||||
('gears', '0009_alter_brass_submitted_by_alter_bullet_submitted_by_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='rig',
|
||||
name='photo',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='rig', to='photos.photo', verbose_name='photo'),
|
||||
),
|
||||
]
|
||||
23
apps/gears/migrations/0011_rig_ballistic_fields.py
Normal file
23
apps/gears/migrations/0011_rig_ballistic_fields.py
Normal file
@@ -0,0 +1,23 @@
|
||||
# Generated by Django 4.2.16 on 2026-03-30 09:39
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gears', '0010_rig_photo'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='rig',
|
||||
name='scope_height_mm',
|
||||
field=models.DecimalField(blank=True, decimal_places=1, max_digits=5, null=True, verbose_name='scope height above bore (mm)'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='rig',
|
||||
name='zero_distance_m',
|
||||
field=models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='zero distance (m)'),
|
||||
),
|
||||
]
|
||||
142
apps/gears/migrations/0012_caliber_fk.py
Normal file
142
apps/gears/migrations/0012_caliber_fk.py
Normal file
@@ -0,0 +1,142 @@
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gears', '0011_rig_ballistic_fields'),
|
||||
('calibers', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
# ── Firearm.caliber ──────────────────────────────────────────────────
|
||||
migrations.RemoveField(
|
||||
model_name='firearm',
|
||||
name='caliber',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='firearm',
|
||||
name='caliber',
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
related_name='+',
|
||||
to='calibers.caliber',
|
||||
verbose_name='caliber',
|
||||
),
|
||||
),
|
||||
|
||||
# ── Suppressor.max_caliber ───────────────────────────────────────────
|
||||
migrations.RemoveField(
|
||||
model_name='suppressor',
|
||||
name='max_caliber',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='suppressor',
|
||||
name='max_caliber',
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
related_name='+',
|
||||
to='calibers.caliber',
|
||||
verbose_name='max caliber',
|
||||
),
|
||||
),
|
||||
|
||||
# ── Magazine.caliber ─────────────────────────────────────────────────
|
||||
migrations.RemoveField(
|
||||
model_name='magazine',
|
||||
name='caliber',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='magazine',
|
||||
name='caliber',
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
related_name='+',
|
||||
to='calibers.caliber',
|
||||
verbose_name='caliber',
|
||||
),
|
||||
),
|
||||
|
||||
# ── Ammo.caliber — remove constraint first ───────────────────────────
|
||||
migrations.RemoveConstraint(
|
||||
model_name='ammo',
|
||||
name='unique_ammo_brand_name_caliber',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='ammo',
|
||||
name='caliber',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ammo',
|
||||
name='caliber',
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
related_name='+',
|
||||
to='calibers.caliber',
|
||||
verbose_name='caliber',
|
||||
),
|
||||
),
|
||||
migrations.AddConstraint(
|
||||
model_name='ammo',
|
||||
constraint=models.UniqueConstraint(
|
||||
fields=['brand', 'name', 'caliber'],
|
||||
name='unique_ammo_brand_name_caliber',
|
||||
),
|
||||
),
|
||||
|
||||
# ── Brass.caliber — remove constraint first ───────────────────────────
|
||||
migrations.RemoveConstraint(
|
||||
model_name='brass',
|
||||
name='unique_brass_brand_caliber',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='brass',
|
||||
name='caliber',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='brass',
|
||||
name='caliber',
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
related_name='+',
|
||||
to='calibers.caliber',
|
||||
verbose_name='caliber',
|
||||
),
|
||||
),
|
||||
migrations.AddConstraint(
|
||||
model_name='brass',
|
||||
constraint=models.UniqueConstraint(
|
||||
fields=['brand', 'caliber'],
|
||||
name='unique_brass_brand_caliber',
|
||||
),
|
||||
),
|
||||
|
||||
# ── ReloadRecipe.caliber ─────────────────────────────────────────────
|
||||
migrations.RemoveField(
|
||||
model_name='reloadrecipe',
|
||||
name='caliber',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='reloadrecipe',
|
||||
name='caliber',
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
related_name='+',
|
||||
to='calibers.caliber',
|
||||
verbose_name='caliber',
|
||||
),
|
||||
),
|
||||
]
|
||||
25
apps/gears/migrations/0013_remove_firearm_action.py
Normal file
25
apps/gears/migrations/0013_remove_firearm_action.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# Generated by Django 4.2.16 on 2026-03-31 12:48
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gears', '0012_caliber_fk'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='ammo',
|
||||
options={'ordering': ['brand', 'name', 'caliber__name'], 'verbose_name': 'ammo', 'verbose_name_plural': 'ammo'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='brass',
|
||||
options={'ordering': ['brand', 'caliber__name'], 'verbose_name': 'brass', 'verbose_name_plural': 'brass'},
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='firearm',
|
||||
name='action',
|
||||
),
|
||||
]
|
||||
16
apps/gears/migrations/0014_reloadrecipe_is_public.py
Normal file
16
apps/gears/migrations/0014_reloadrecipe_is_public.py
Normal file
@@ -0,0 +1,16 @@
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gears', '0013_remove_firearm_action'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='reloadrecipe',
|
||||
name='is_public',
|
||||
field=models.BooleanField(default=False, verbose_name='public'),
|
||||
),
|
||||
]
|
||||
0
apps/gears/migrations/__init__.py
Normal file
0
apps/gears/migrations/__init__.py
Normal file
86
apps/gears/migrations/gears_0006_component_status.py
Normal file
86
apps/gears/migrations/gears_0006_component_status.py
Normal file
@@ -0,0 +1,86 @@
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gears', '0005_rig_is_public'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
# Primer
|
||||
migrations.AddField(
|
||||
model_name='primer',
|
||||
name='status',
|
||||
field=models.CharField(
|
||||
choices=[('PENDING', 'Pending Verification'), ('VERIFIED', 'Verified'), ('REJECTED', 'Rejected')],
|
||||
default='VERIFIED', max_length=10, verbose_name='status',
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='primer',
|
||||
name='submitted_by',
|
||||
field=models.ForeignKey(
|
||||
blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL,
|
||||
related_name='submitted_primers', to=settings.AUTH_USER_MODEL,
|
||||
verbose_name='submitted by',
|
||||
),
|
||||
),
|
||||
# Brass
|
||||
migrations.AddField(
|
||||
model_name='brass',
|
||||
name='status',
|
||||
field=models.CharField(
|
||||
choices=[('PENDING', 'Pending Verification'), ('VERIFIED', 'Verified'), ('REJECTED', 'Rejected')],
|
||||
default='VERIFIED', max_length=10, verbose_name='status',
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='brass',
|
||||
name='submitted_by',
|
||||
field=models.ForeignKey(
|
||||
blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL,
|
||||
related_name='submitted_brasss', to=settings.AUTH_USER_MODEL,
|
||||
verbose_name='submitted by',
|
||||
),
|
||||
),
|
||||
# Bullet
|
||||
migrations.AddField(
|
||||
model_name='bullet',
|
||||
name='status',
|
||||
field=models.CharField(
|
||||
choices=[('PENDING', 'Pending Verification'), ('VERIFIED', 'Verified'), ('REJECTED', 'Rejected')],
|
||||
default='VERIFIED', max_length=10, verbose_name='status',
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='bullet',
|
||||
name='submitted_by',
|
||||
field=models.ForeignKey(
|
||||
blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL,
|
||||
related_name='submitted_bullets', to=settings.AUTH_USER_MODEL,
|
||||
verbose_name='submitted by',
|
||||
),
|
||||
),
|
||||
# Powder
|
||||
migrations.AddField(
|
||||
model_name='powder',
|
||||
name='status',
|
||||
field=models.CharField(
|
||||
choices=[('PENDING', 'Pending Verification'), ('VERIFIED', 'Verified'), ('REJECTED', 'Rejected')],
|
||||
default='VERIFIED', max_length=10, verbose_name='status',
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='powder',
|
||||
name='submitted_by',
|
||||
field=models.ForeignKey(
|
||||
blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL,
|
||||
related_name='submitted_powders', to=settings.AUTH_USER_MODEL,
|
||||
verbose_name='submitted by',
|
||||
),
|
||||
),
|
||||
]
|
||||
Reference in New Issue
Block a user