211 lines
5.9 KiB
Python
211 lines
5.9 KiB
Python
"""
|
|
Favorites models for collections, tags and price monitoring.
|
|
"""
|
|
from django.db import models
|
|
from django.conf import settings
|
|
|
|
|
|
class Favorite(models.Model):
|
|
"""User product favorites/collections."""
|
|
|
|
id = models.AutoField(primary_key=True)
|
|
user = models.ForeignKey(
|
|
settings.AUTH_USER_MODEL,
|
|
on_delete=models.CASCADE,
|
|
related_name='favorites',
|
|
verbose_name='用户'
|
|
)
|
|
product = models.ForeignKey(
|
|
'products.Product',
|
|
on_delete=models.CASCADE,
|
|
related_name='favorites',
|
|
verbose_name='商品'
|
|
)
|
|
website = models.ForeignKey(
|
|
'products.Website',
|
|
on_delete=models.CASCADE,
|
|
related_name='favorites',
|
|
verbose_name='网站'
|
|
)
|
|
created_at = models.DateTimeField('创建时间', auto_now_add=True)
|
|
|
|
class Meta:
|
|
db_table = 'favorites'
|
|
verbose_name = '收藏'
|
|
verbose_name_plural = '收藏'
|
|
unique_together = ['user', 'product', 'website']
|
|
indexes = [
|
|
models.Index(fields=["user", "created_at"]),
|
|
]
|
|
|
|
def __str__(self):
|
|
return f"{self.user} - {self.product.name}"
|
|
|
|
|
|
class FavoriteTag(models.Model):
|
|
"""Favorite collection tags for organizing collections."""
|
|
|
|
id = models.AutoField(primary_key=True)
|
|
user = models.ForeignKey(
|
|
settings.AUTH_USER_MODEL,
|
|
on_delete=models.CASCADE,
|
|
related_name='favorite_tags',
|
|
verbose_name='用户'
|
|
)
|
|
name = models.CharField('标签名', max_length=100)
|
|
color = models.CharField('颜色', max_length=20, default='#6366f1')
|
|
description = models.TextField('描述', blank=True, null=True)
|
|
created_at = models.DateTimeField('创建时间', auto_now_add=True)
|
|
|
|
class Meta:
|
|
db_table = 'favoriteTags'
|
|
verbose_name = '收藏标签'
|
|
verbose_name_plural = '收藏标签'
|
|
unique_together = ['user', 'name']
|
|
indexes = [
|
|
models.Index(fields=["user", "created_at"]),
|
|
]
|
|
|
|
def __str__(self):
|
|
return self.name
|
|
|
|
|
|
class FavoriteTagMapping(models.Model):
|
|
"""Junction table for favorites and tags."""
|
|
|
|
id = models.AutoField(primary_key=True)
|
|
favorite = models.ForeignKey(
|
|
Favorite,
|
|
on_delete=models.CASCADE,
|
|
related_name='tag_mappings',
|
|
verbose_name='收藏'
|
|
)
|
|
tag = models.ForeignKey(
|
|
FavoriteTag,
|
|
on_delete=models.CASCADE,
|
|
related_name='favorite_mappings',
|
|
verbose_name='标签'
|
|
)
|
|
created_at = models.DateTimeField('创建时间', auto_now_add=True)
|
|
|
|
class Meta:
|
|
db_table = 'favoriteTagMappings'
|
|
verbose_name = '收藏标签映射'
|
|
verbose_name_plural = '收藏标签映射'
|
|
unique_together = ['favorite', 'tag']
|
|
indexes = [
|
|
models.Index(fields=["tag", "created_at"]),
|
|
]
|
|
|
|
def __str__(self):
|
|
return f"{self.favorite} - {self.tag.name}"
|
|
|
|
|
|
class PriceMonitor(models.Model):
|
|
"""Price monitoring for favorites."""
|
|
|
|
id = models.AutoField(primary_key=True)
|
|
favorite = models.OneToOneField(
|
|
Favorite,
|
|
on_delete=models.CASCADE,
|
|
related_name='price_monitor',
|
|
verbose_name='收藏'
|
|
)
|
|
user = models.ForeignKey(
|
|
settings.AUTH_USER_MODEL,
|
|
on_delete=models.CASCADE,
|
|
related_name='price_monitors',
|
|
verbose_name='用户'
|
|
)
|
|
current_price = models.DecimalField(
|
|
'当前价格',
|
|
max_digits=10,
|
|
decimal_places=2,
|
|
blank=True,
|
|
null=True
|
|
)
|
|
target_price = models.DecimalField(
|
|
'目标价格',
|
|
max_digits=10,
|
|
decimal_places=2,
|
|
blank=True,
|
|
null=True
|
|
)
|
|
lowest_price = models.DecimalField(
|
|
'最低价',
|
|
max_digits=10,
|
|
decimal_places=2,
|
|
blank=True,
|
|
null=True
|
|
)
|
|
highest_price = models.DecimalField(
|
|
'最高价',
|
|
max_digits=10,
|
|
decimal_places=2,
|
|
blank=True,
|
|
null=True
|
|
)
|
|
notify_enabled = models.BooleanField('是否通知', default=True)
|
|
notify_on_target = models.BooleanField('目标价提醒', default=True)
|
|
last_notified_price = models.DecimalField(
|
|
'上次通知价格',
|
|
max_digits=10,
|
|
decimal_places=2,
|
|
blank=True,
|
|
null=True
|
|
)
|
|
is_active = models.BooleanField('是否激活', default=True)
|
|
created_at = models.DateTimeField('创建时间', auto_now_add=True)
|
|
updated_at = models.DateTimeField('更新时间', auto_now=True)
|
|
|
|
class Meta:
|
|
db_table = 'priceMonitors'
|
|
verbose_name = '价格监控'
|
|
verbose_name_plural = '价格监控'
|
|
indexes = [
|
|
models.Index(fields=["user", "is_active"]),
|
|
]
|
|
|
|
def __str__(self):
|
|
return f"Monitor: {self.favorite}"
|
|
|
|
|
|
class PriceHistory(models.Model):
|
|
"""Price history tracking."""
|
|
|
|
id = models.AutoField(primary_key=True)
|
|
monitor = models.ForeignKey(
|
|
PriceMonitor,
|
|
on_delete=models.CASCADE,
|
|
related_name='history',
|
|
verbose_name='监控'
|
|
)
|
|
price = models.DecimalField('价格', max_digits=10, decimal_places=2)
|
|
price_change = models.DecimalField(
|
|
'价格变化',
|
|
max_digits=10,
|
|
decimal_places=2,
|
|
blank=True,
|
|
null=True
|
|
)
|
|
percent_change = models.DecimalField(
|
|
'变化百分比',
|
|
max_digits=5,
|
|
decimal_places=2,
|
|
blank=True,
|
|
null=True
|
|
)
|
|
recorded_at = models.DateTimeField('记录时间', auto_now_add=True)
|
|
|
|
class Meta:
|
|
db_table = 'priceHistory'
|
|
verbose_name = '价格历史'
|
|
verbose_name_plural = '价格历史'
|
|
ordering = ['-recorded_at']
|
|
indexes = [
|
|
models.Index(fields=["monitor", "recorded_at"]),
|
|
]
|
|
|
|
def __str__(self):
|
|
return f"{self.monitor.favorite} - {self.price}"
|