From 02e18b2f72f1e549a23e327b48804ec60f54fff5 Mon Sep 17 00:00:00 2001 From: vincent porte Date: Tue, 18 Jul 2023 16:33:33 +0200 Subject: [PATCH] =?UTF-8?q?feat(upvotes):=C2=A0set=20GenericForeignKey=20o?= =?UTF-8?q?n=20UpVote=20model,=20manage=20data=20migration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lacommunaute/forum_upvote/admin.py | 10 +-- .../migrations/0003_auto_20230718_1509.py | 79 +++++++++++++++++++ lacommunaute/forum_upvote/models.py | 16 ++-- 3 files changed, 89 insertions(+), 16 deletions(-) create mode 100644 lacommunaute/forum_upvote/migrations/0003_auto_20230718_1509.py diff --git a/lacommunaute/forum_upvote/admin.py b/lacommunaute/forum_upvote/admin.py index 3307f0533..d2b0d3465 100644 --- a/lacommunaute/forum_upvote/admin.py +++ b/lacommunaute/forum_upvote/admin.py @@ -4,18 +4,14 @@ class UpVoteAdmin(admin.ModelAdmin): - list_display = ("voter", "post", "created_at") - raw_id_fields = ( - "voter", - "post", - ) + list_display = ("voter", "created_at") + raw_id_fields = ("voter",) class CertifiedPostAdmin(admin.ModelAdmin): - list_display = ("topic", "post", "user") + list_display = ("topic", "user") raw_id_fields = ( "topic", - "post", "user", ) diff --git a/lacommunaute/forum_upvote/migrations/0003_auto_20230718_1509.py b/lacommunaute/forum_upvote/migrations/0003_auto_20230718_1509.py new file mode 100644 index 000000000..a39b9e78f --- /dev/null +++ b/lacommunaute/forum_upvote/migrations/0003_auto_20230718_1509.py @@ -0,0 +1,79 @@ +import django.db.models.deletion +from django.contrib.contenttypes.models import ContentType +from django.db import migrations, models + + +def move_forward_foreign_key_to_generic_foreign_key(apps, schema_editor): + UpVote = apps.get_model("forum_upvote", "UpVote") + ContentType = apps.get_model("contenttypes", "ContentType") + + UpVote.objects.filter(post__isnull=True).delete() + + for upvote in UpVote.objects.all(): + upvote.content_object = upvote.post + upvote.object_id = upvote.post_id + upvote.content_type = ContentType.objects.get_for_model(upvote.post) + upvote.save() + + +def move_back_generic_foreign_key_to_foreign_key(apps, schema_editor): + UpVote = apps.get_model("forum_upvote", "UpVote") + Post = apps.get_model("forum_conversation", "Post") + + post_content_type_id = ContentType.objects.get(model="post", app_label="forum_conversation").id + UpVote.objects.exclude(content_type_id=post_content_type_id).delete() + + for upvote in UpVote.objects.all(): + upvote.post = Post.objects.get(id=upvote.object_id) + upvote.save() + + +class Migration(migrations.Migration): + dependencies = [ + ("contenttypes", "0002_remove_content_type_name"), + ("forum_upvote", "0002_certifiedpost"), + ] + + operations = [ + migrations.AlterUniqueTogether( + name="upvote", + unique_together=set(), + ), + migrations.AddField( + model_name="upvote", + name="content_type", + field=models.ForeignKey( + null=True, on_delete=django.db.models.deletion.CASCADE, to="contenttypes.contenttype" + ), + ), + migrations.AddField( + model_name="upvote", + name="object_id", + field=models.PositiveIntegerField(null=True), + ), + migrations.RunPython( + move_forward_foreign_key_to_generic_foreign_key, + move_back_generic_foreign_key_to_foreign_key, + ), + migrations.AlterUniqueTogether( + name="upvote", + unique_together={("voter", "content_type", "object_id")}, + ), + migrations.AlterField( + model_name="upvote", + name="content_type", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="contenttypes.contenttype", + ), + ), + migrations.AlterField( + model_name="upvote", + name="object_id", + field=models.PositiveIntegerField(), + ), + migrations.RemoveField( + model_name="upvote", + name="post", + ), + ] diff --git a/lacommunaute/forum_upvote/models.py b/lacommunaute/forum_upvote/models.py index 5823664b9..4a308b517 100644 --- a/lacommunaute/forum_upvote/models.py +++ b/lacommunaute/forum_upvote/models.py @@ -1,4 +1,6 @@ from django.conf import settings +from django.contrib.contenttypes.fields import GenericForeignKey +from django.contrib.contenttypes.models import ContentType from django.db import models from machina.models.abstract_models import DatedModel @@ -15,20 +17,16 @@ class UpVote(models.Model): verbose_name="Voter", ) - post = models.ForeignKey( - Post, - related_name="upvotes", - blank=True, - null=True, - on_delete=models.SET_NULL, - verbose_name="Post", - ) + content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) + object_id = models.PositiveIntegerField() + + content_object = GenericForeignKey("content_type", "object_id") created_at = models.DateTimeField(auto_now_add=True, db_index=True, verbose_name="Creation date") objects = models.Manager() class Meta: - unique_together = ["voter", "post"] + unique_together = ["voter", "content_type", "object_id"] ordering = [ "-created_at", ]