Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions forum/backends/mysql/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -1223,12 +1223,16 @@ def retire_all_content(
comments = Comment.objects.filter(author__pk=user_id)
for comment in comments:
comment.body = RETIRED_BODY
comment.retired_username = username
comment.author_username = username
comment.save()

comment_threads = CommentThread.objects.filter(author__pk=user_id)
for comment_thread in comment_threads:
comment_thread.body = RETIRED_BODY
comment_thread.title = RETIRED_TITLE
comment_thread.retired_username = username
comment_thread.author_username = username
comment_thread.save()

@staticmethod
Expand Down Expand Up @@ -1949,6 +1953,10 @@ def replace_username_in_all_content(user_id: str, username: str) -> None:
user = User.objects.get(pk=user_id)
user.username = username
user.save()

# Update author_username in all content
Comment.objects.filter(author=user).update(author_username=username)
CommentThread.objects.filter(author=user).update(author_username=username)
except User.DoesNotExist as exc:
raise ValueError("User does not exist") from exc

Expand Down
30 changes: 28 additions & 2 deletions forum/backends/mysql/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,18 @@ class Content(models.Model):
author: models.ForeignKey[User, User] = models.ForeignKey(
User, on_delete=models.CASCADE
)
author_username: models.CharField[Optional[str], str] = models.CharField(
max_length=255,
null=True,
blank=True,
help_text="Username at time of posting, preserved for historical accuracy",
)
retired_username: models.CharField[Optional[str], str] = models.CharField(
max_length=255,
null=True,
blank=True,
help_text="Username to display if author account was retired",
)
course_id: models.CharField[str, str] = models.CharField(max_length=255)
body: models.TextField[str, str] = models.TextField()
visible: models.BooleanField[bool, bool] = models.BooleanField(default=True)
Expand Down Expand Up @@ -184,6 +196,16 @@ def get_votes(self) -> dict[str, Any]:
votes["count"] = votes["count"]
return votes

def save(self, *args: Any, **kwargs: Any) -> None:
"""Set author_username on creation if not already set."""
if not self.pk and not self.author_username:
# On creation, store the current username
if self.retired_username:
self.author_username = self.retired_username
elif self.author:
self.author_username = self.author.username
super().save(*args, **kwargs)

def to_dict(self) -> dict[str, Any]:
"""Return a dictionary representation of the content."""
raise NotImplementedError
Expand Down Expand Up @@ -288,7 +310,9 @@ def to_dict(self) -> dict[str, Any]:
"closed_by_id": str(self.closed_by.pk) if self.closed_by else None,
"close_reason_code": self.close_reason_code,
"author_id": str(self.author.pk),
"author_username": self.author.username,
"author_username": self.author_username
or self.retired_username
or self.author.username,
"updated_at": self.updated_at,
"created_at": self.created_at,
"last_activity_at": self.last_activity_at,
Expand Down Expand Up @@ -469,7 +493,9 @@ def to_dict(self) -> dict[str, Any]:
"author_id": str(self.author.pk),
"comment_thread_id": str(self.comment_thread.pk),
"child_count": self.child_count,
"author_username": self.author.username,
"author_username": self.author_username
or self.retired_username
or self.author.username,
"sk": str(self.pk),
"updated_at": self.updated_at,
"created_at": self.created_at,
Expand Down
32 changes: 32 additions & 0 deletions forum/migration_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,29 @@ def create_or_update_thread(thread_data: dict[str, Any]) -> None:
author = get_user_or_none(thread_data["author_id"])
if not author:
return

# Preserve author_username from MongoDB (historical username)
author_username = thread_data.get("author_username")

# Preserve retired_username from MongoDB
retired_username = thread_data.get("retired_username")

# If author_username is not provided, use retired_username or fallback to current username
if not author_username:
if retired_username:
author_username = retired_username
else:
author_username = author.username

mongo_thread_id = str(thread_data["_id"])
mongo_content, _ = MongoContent.objects.get_or_create(
mongo_id=mongo_thread_id,
)
if not mongo_content.content_object_id:
thread = CommentThread.objects.create(
author=author,
author_username=author_username,
retired_username=retired_username,
course_id=thread_data["course_id"],
title=get_trunc_title(thread_data.get("title", "")),
body=thread_data["body"],
Expand Down Expand Up @@ -128,6 +144,20 @@ def create_or_update_comment(comment_data: dict[str, Any]) -> None:
author = get_user_or_none(comment_data["author_id"])
if not author:
return

# Preserve author_username from MongoDB (historical username)
author_username = comment_data.get("author_username")

# Preserve retired_username from MongoDB
retired_username = comment_data.get("retired_username")

# If author_username is not provided, use retired_username or fallback to current username
if not author_username:
if retired_username:
author_username = retired_username
else:
author_username = author.username

mongo_thread_id = str(comment_data["comment_thread_id"])
mongo_thread = MongoContent.objects.filter(mongo_id=mongo_thread_id).first()
if not mongo_thread:
Expand Down Expand Up @@ -169,6 +199,8 @@ def create_or_update_comment(comment_data: dict[str, Any]) -> None:
if not mongo_comment.content_object_id:
comment = Comment.objects.create(
author=author,
author_username=author_username,
retired_username=retired_username,
comment_thread=thread,
parent=parent,
course_id=comment_data["course_id"],
Expand Down
43 changes: 43 additions & 0 deletions forum/migrations/0004_add_author_username_fields.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Generated by Django 4.2 on 2024-10-24 13:36

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("forum", "0003_alter_commentthread_title"),
]

operations = [
migrations.AddField(
model_name="comment",
name="author_username",
field=models.CharField(
blank=True,
help_text="Username at time of posting, preserved for historical accuracy",
max_length=255,
null=True,
),
),
migrations.AddField(
model_name="commentthread",
name="author_username",
field=models.CharField(
blank=True,
help_text="Username at time of posting, preserved for historical accuracy",
max_length=255,
null=True,
),
),
migrations.AddField(
model_name="commentthread",
name="retired_username",
field=models.CharField(
blank=True,
help_text="Username to display if author account was retired",
max_length=255,
null=True,
),
),
]
Loading