feat: Introduce lists and reviews apps, refactor user list functionality from accounts, and add user profile fields.

This commit is contained in:
pacnpal
2025-12-26 09:27:44 -05:00
parent ed04b30469
commit cd8868a591
37 changed files with 5900 additions and 281 deletions

View File

@@ -11,6 +11,7 @@ from django.utils import timezone
from apps.core.history import TrackedModel
from apps.core.choices import RichChoiceField
import pghistory
# from django_cloudflareimages_toolkit.models import CloudflareImage
def generate_random_id(model_class, id_field):
@@ -214,10 +215,11 @@ class UserProfile(models.Model):
help_text="Legacy display name field - use User.display_name instead",
)
avatar = models.ForeignKey(
'django_cloudflareimages_toolkit.CloudflareImage',
"django_cloudflareimages_toolkit.CloudflareImage",
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name="user_profiles",
help_text="User's avatar image",
)
pronouns = models.CharField(
@@ -225,6 +227,16 @@ class UserProfile(models.Model):
)
bio = models.TextField(max_length=500, blank=True, help_text="User biography")
location = models.CharField(
max_length=100, blank=True, help_text="User's location (City, Country)"
)
unit_system = RichChoiceField(
choice_group="unit_systems",
domain="accounts",
max_length=10,
default="metric",
help_text="Preferred measurement system",
)
# Social media links
twitter = models.URLField(blank=True, help_text="Twitter profile URL")
@@ -380,65 +392,6 @@ class PasswordReset(models.Model):
verbose_name_plural = "Password Resets"
# @pghistory.track()
class TopList(TrackedModel):
user = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name="top_lists",
help_text="User who created this list",
)
title = models.CharField(max_length=100, help_text="Title of the top list")
category = RichChoiceField(
choice_group="top_list_categories",
domain="accounts",
max_length=2,
help_text="Category of items in this list",
)
description = models.TextField(blank=True, help_text="Description of the list")
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta(TrackedModel.Meta):
verbose_name = "Top List"
verbose_name_plural = "Top Lists"
ordering = ["-updated_at"]
def __str__(self):
return (
f"{self.user.get_display_name()}'s {self.category} Top List: {self.title}"
)
# @pghistory.track()
class TopListItem(TrackedModel):
top_list = models.ForeignKey(
TopList,
on_delete=models.CASCADE,
related_name="items",
help_text="Top list this item belongs to",
)
content_type = models.ForeignKey(
"contenttypes.ContentType",
on_delete=models.CASCADE,
help_text="Type of item (park, ride, etc.)",
)
object_id = models.PositiveIntegerField(help_text="ID of the item")
rank = models.PositiveIntegerField(help_text="Position in the list")
notes = models.TextField(blank=True, help_text="User's notes about this item")
class Meta(TrackedModel.Meta):
verbose_name = "Top List Item"
verbose_name_plural = "Top List Items"
ordering = ["rank"]
unique_together = [["top_list", "rank"]]
def __str__(self):
return f"#{self.rank} in {self.top_list.title}"
@pghistory.track()