change linked orderpositions to many-to-many

This commit is contained in:
Richard Schreiber
2025-11-28 13:55:01 +01:00
parent 589f51454e
commit 20f98f4cfe
3 changed files with 88 additions and 4 deletions

View File

@@ -0,0 +1,30 @@
# Generated by Django 4.2.26 on 2025-11-24 11:32
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("pretixbase", "0296_invoice_invoice_from_state"),
]
operations = [
migrations.AddField(
model_name="reusablemedium",
name="secret",
field=models.CharField(max_length=200, null=True),
),
# use temporary related_name "linked_mediums" for ManyToManyField, so we can migrate existing data
migrations.AddField(
model_name="reusablemedium",
name="linked_orderpositions",
field=models.ManyToManyField(
related_name="linked_mediums", to="pretixbase.orderposition"
),
),
migrations.RunSQL(
sql="INSERT INTO pretixbase_reusablemedium_linked_orderpositions (reusablemedium_id, orderposition_id) SELECT id, linked_orderposition_id FROM pretixbase_reusablemedium;",
reverse_sql="DELETE FROM pretixbase_reusablemedium_linked_orderpositions;",
),
]

View File

@@ -0,0 +1,46 @@
# Generated by Django 4.2.26 on 2025-11-24 11:32
from django.db import migrations, models
def reverse(apps, schema_editor):
ReusableMedium = apps.get_model('pretixbase', 'ReusableMedium')
qs = ReusableMedium.linked_orderpositions.through.objects
objs = []
# get last added orderposition from linked_orderpositions
for rm_id, op_id in qs.filter(id__in=qs.values("reusablemedium_id").annotate(max_id=models.Max('id')).values('max_id')).values_list("reusablemedium_id", "orderposition_id"):
#obj = ReusableMedium.objects.get(id=rm_id)
#obj.linked_orderposition_id = op_id
obj = ReusableMedium(
id=rm_id,
linked_orderposition_id=op_id,
)
objs.append(obj)
ReusableMedium.objects.bulk_update(objs, ['linked_orderposition_id'])
class Migration(migrations.Migration):
dependencies = [
("pretixbase", "0297_add_reusablemedium_secret"),
]
operations = [
# according to the docs, UPDATE FROM should run similarly on sqlite and postgres, but I could not get it to work
# so roll back the data migration with code before deleting data from through-table in 0297
migrations.RunPython(migrations.RunPython.noop, reverse),
migrations.RemoveField(
model_name="reusablemedium",
name="linked_orderposition",
),
# change related_name for new ManyToManyField to previously used linked_media
migrations.AlterField(
model_name="reusablemedium",
name="linked_orderpositions",
field=models.ManyToManyField(
related_name="linked_media", to="pretixbase.orderposition"
),
),
]

View File

@@ -72,6 +72,11 @@ class ReusableMedium(LoggedModel):
max_length=200,
verbose_name=pgettext_lazy('reusable_medium', 'Identifier'),
)
secret = models.CharField(
max_length=200,
verbose_name=pgettext_lazy('reusable_medium', 'Secret'),
null=True, blank=True
)
active = models.BooleanField(
verbose_name=_('Active'),
@@ -89,12 +94,10 @@ class ReusableMedium(LoggedModel):
on_delete=models.SET_NULL,
verbose_name=_('Customer account'),
)
linked_orderposition = models.ForeignKey(
linked_orderpositions = models.ManyToManyField(
OrderPosition,
null=True, blank=True,
related_name='linked_media',
on_delete=models.SET_NULL,
verbose_name=_('Linked ticket'),
verbose_name=_('Linked tickets'),
)
linked_giftcard = models.ForeignKey(
GiftCard,
@@ -111,6 +114,11 @@ class ReusableMedium(LoggedModel):
objects = ReusableMediumQuerySetManager()
@cached_property
def linked_orderposition(self):
# always return last added linked_orderposition to make it behave backwardscompatible
return self.linked_orderpositions.order_by('pk').last()
@cached_property
def media_type(self):
return MEDIA_TYPES[self.type]