Convert verification_model to ForeignKey with data migration
- Convert CodeBatch.verification_model from TextField to ForeignKey(VerificationModel) - Add ForeignKey relationship to CodeBatchResource API - Update QrVerifyView to use verification_model.name instead of string - Create data migration to: - Rename old TextField temporarily - Add new ForeignKey field - Migrate existing model names to VerificationModel entries - Link batches to VerificationModel records - Remove old TextField - GenericManager will now show dropdown/selector UI automatically
This commit is contained in:
parent
2c74d59d37
commit
719ccd6477
@ -0,0 +1,80 @@
|
|||||||
|
# Generated by Django 4.2.23 on 2025-11-25 22:38
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
def migrate_verification_model_data(apps, schema_editor):
|
||||||
|
"""Migrate data from TextField to ForeignKey"""
|
||||||
|
CodeBatch = apps.get_model('products', 'CodeBatch')
|
||||||
|
VerificationModel = apps.get_model('products', 'VerificationModel')
|
||||||
|
|
||||||
|
# Query the database directly to get the old TextField values
|
||||||
|
from django.db import connection
|
||||||
|
with connection.cursor() as cursor:
|
||||||
|
# Query the old field (verification_model_old after rename)
|
||||||
|
cursor.execute("SELECT DISTINCT verification_model_old FROM products_codebatch WHERE verification_model_old IS NOT NULL AND verification_model_old != ''")
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
unique_model_names = {row[0] for row in rows if row[0]}
|
||||||
|
|
||||||
|
# Create VerificationModel entries for each unique model name
|
||||||
|
model_map = {}
|
||||||
|
for model_name in unique_model_names:
|
||||||
|
vm, created = VerificationModel.objects.get_or_create(name=model_name)
|
||||||
|
model_map[model_name] = vm
|
||||||
|
|
||||||
|
# Update all CodeBatch records to use the ForeignKey
|
||||||
|
with connection.cursor() as cursor:
|
||||||
|
cursor.execute("SELECT id, verification_model_old FROM products_codebatch WHERE verification_model_old IS NOT NULL AND verification_model_old != ''")
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
for batch_id, model_name in rows:
|
||||||
|
if model_name in model_map:
|
||||||
|
vm = model_map[model_name]
|
||||||
|
CodeBatch.objects.filter(pk=batch_id).update(verification_model=vm)
|
||||||
|
|
||||||
|
|
||||||
|
def reverse_migrate_verification_model_data(apps, schema_editor):
|
||||||
|
"""Reverse migration: convert ForeignKey back to TextField"""
|
||||||
|
CodeBatch = apps.get_model('products', 'CodeBatch')
|
||||||
|
# Extract the name from the ForeignKey and set it in the old field
|
||||||
|
from django.db import connection
|
||||||
|
with connection.cursor() as cursor:
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT cb.id, vm.name
|
||||||
|
FROM products_codebatch cb
|
||||||
|
LEFT JOIN products_verificationmodel vm ON cb.verification_model_id = vm.id
|
||||||
|
WHERE cb.verification_model_id IS NOT NULL
|
||||||
|
""")
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
for batch_id, model_name in rows:
|
||||||
|
if model_name:
|
||||||
|
CodeBatch.objects.filter(pk=batch_id).update(verification_model_old=model_name)
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('products', '0110_add_verification_model'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
# Step 1: Rename the old TextField to a temporary name
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name='codebatch',
|
||||||
|
old_name='verification_model',
|
||||||
|
new_name='verification_model_old',
|
||||||
|
),
|
||||||
|
# Step 2: Add the new ForeignKey field
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='codebatch',
|
||||||
|
name='verification_model',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='batches', to='products.verificationmodel', verbose_name='验证模型(可选,留空使用默认模型)'),
|
||||||
|
),
|
||||||
|
# Step 3: Migrate the data
|
||||||
|
migrations.RunPython(migrate_verification_model_data, reverse_migrate_verification_model_data),
|
||||||
|
# Step 4: Remove the old TextField
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='codebatch',
|
||||||
|
name='verification_model_old',
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -194,8 +194,9 @@ class CodeBatch(models.Model):
|
|||||||
verbose_name="小程序入口路径(可选)")
|
verbose_name="小程序入口路径(可选)")
|
||||||
mini_prog_entry_env_version = models.CharField(max_length=128, null=True, blank=True, default='release',
|
mini_prog_entry_env_version = models.CharField(max_length=128, null=True, blank=True, default='release',
|
||||||
verbose_name="小程序入口环境版本(可选), 默认release。如为trial则进入体验版")
|
verbose_name="小程序入口环境版本(可选), 默认release。如为trial则进入体验版")
|
||||||
verification_model = models.TextField(null=True, blank=True,
|
verification_model = models.ForeignKey('VerificationModel', related_name='batches', null=True, blank=True,
|
||||||
verbose_name="验证模型名称(可选,留空使用默认模型)")
|
on_delete=models.SET_NULL,
|
||||||
|
verbose_name="验证模型(可选,留空使用默认模型)")
|
||||||
|
|
||||||
def gen_code(self, n):
|
def gen_code(self, n):
|
||||||
a = 10 ** (self.num_digits - 1)
|
a = 10 ** (self.num_digits - 1)
|
||||||
|
|||||||
@ -326,6 +326,7 @@ class ProductPropertyResource(BaseResource):
|
|||||||
|
|
||||||
class CodeBatchResource(BaseResource):
|
class CodeBatchResource(BaseResource):
|
||||||
tenant = ForeignKey(TenantResource, 'tenant', null=True, blank=True)
|
tenant = ForeignKey(TenantResource, 'tenant', null=True, blank=True)
|
||||||
|
verification_model = ForeignKey(VerificationModelResource, 'verification_model', null=True, blank=True)
|
||||||
class Meta:
|
class Meta:
|
||||||
queryset = CodeBatch.objects.all().order_by('-pk')
|
queryset = CodeBatch.objects.all().order_by('-pk')
|
||||||
resource_name = 'code-batch'
|
resource_name = 'code-batch'
|
||||||
@ -739,7 +740,7 @@ class QrVerifyView(BaseView):
|
|||||||
t = threading.Thread(target=oss_put, args=(image_name, img_data))
|
t = threading.Thread(target=oss_put, args=(image_name, img_data))
|
||||||
t.run()
|
t.run()
|
||||||
if sc.batch.feature_comparison_threshold > 0.01:
|
if sc.batch.feature_comparison_threshold > 0.01:
|
||||||
model_name = sc.batch.verification_model if sc.batch.verification_model else None
|
model_name = sc.batch.verification_model.name if sc.batch.verification_model else None
|
||||||
used_model = self.do_v5_qr_verify(imgs, messages, model_name=model_name)
|
used_model = self.do_v5_qr_verify(imgs, messages, model_name=model_name)
|
||||||
sd.verification_model = used_model if used_model else None
|
sd.verification_model = used_model if used_model else None
|
||||||
else:
|
else:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user