daren/apps/daren_detail/models.py
2025-05-23 12:11:03 +08:00

484 lines
22 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from django.db import models
# from apps.daren_detail.models import User
# 修改User模型导入
from apps.user.models import User
from apps.brands.models import Campaign as BrandCampaign
# 新增模型:协作指标数据
class CollaborationMetrics(models.Model):
"""协作指标数据模型Collaboration Metrics部分"""
avg_commission_rate = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="平均佣金率(%)")
products_count = models.IntegerField(verbose_name="产品数量")
brand_collaborations = models.IntegerField(verbose_name="品牌合作数量")
min_product_price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="最低产品价格($)")
max_product_price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="最高产品价格($)")
# 时间范围
start_date = models.DateField(verbose_name="开始日期")
end_date = models.DateField(verbose_name="结束日期")
# 所属创作者
creator = models.ForeignKey('CreatorProfile', on_delete=models.CASCADE, related_name="collaboration_metrics",
verbose_name="创作者")
# 时间戳
create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
update_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")
class Meta:
verbose_name = "协作指标"
verbose_name_plural = verbose_name
db_table = "collaboration_metrics"
def __str__(self):
return f"{self.creator.name}的协作指标 ({self.start_date} - {self.end_date})"
# 新增模型:视频指标数据
class VideoMetrics(models.Model):
"""视频指标数据模型Video和Shoppable Video部分"""
video_type = models.CharField(max_length=50, choices=[
('regular', '普通视频'),
('shoppable', '可购物视频')
], default='regular', verbose_name="视频类型")
gpm = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="视频GPM($)")
videos_count = models.IntegerField(verbose_name="视频数量")
avg_views = models.DecimalField(max_digits=12, decimal_places=2, verbose_name="平均观看量")
avg_engagement = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="平均互动率(%)")
avg_likes = models.IntegerField(verbose_name="平均点赞数")
# 时间范围
start_date = models.DateField(verbose_name="开始日期")
end_date = models.DateField(verbose_name="结束日期")
# 所属创作者
creator = models.ForeignKey('CreatorProfile', on_delete=models.CASCADE, related_name="video_metrics",
verbose_name="创作者")
# 时间戳
create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
update_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")
class Meta:
verbose_name = "视频指标"
verbose_name_plural = verbose_name
db_table = "video_metrics"
unique_together = ('creator', 'video_type', 'start_date', 'end_date') # 同一创作者同一时间段同一类型只能有一条记录
def __str__(self):
return f"{self.creator.name}{self.get_video_type_display()}指标 ({self.start_date} - {self.end_date})"
# 新增模型:直播指标数据
class LiveMetrics(models.Model):
"""直播指标数据模型LIVE和Shoppable LIVE部分"""
live_type = models.CharField(max_length=50, choices=[
('regular', '普通直播'),
('shoppable', '可购物直播')
], default='regular', verbose_name="直播类型")
gpm = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="直播GPM($)")
lives_count = models.IntegerField(verbose_name="直播数量")
avg_views = models.DecimalField(max_digits=12, decimal_places=2, verbose_name="平均观看量")
avg_engagement = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="平均互动率(%)")
avg_likes = models.IntegerField(verbose_name="平均点赞数")
# 时间范围
start_date = models.DateField(verbose_name="开始日期")
end_date = models.DateField(verbose_name="结束日期")
# 所属创作者
creator = models.ForeignKey('CreatorProfile', on_delete=models.CASCADE, related_name="live_metrics",
verbose_name="创作者")
# 时间戳
create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
update_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")
class Meta:
verbose_name = "直播指标"
verbose_name_plural = verbose_name
db_table = "live_metrics"
unique_together = ('creator', 'live_type', 'start_date', 'end_date') # 同一创作者同一时间段同一类型只能有一条记录
def __str__(self):
return f"{self.creator.name}{self.get_live_type_display()}指标 ({self.start_date} - {self.end_date})"
class CreatorProfile(models.Model):
"""达人信息模型,用于筛选功能"""
# 基本信息
name = models.CharField(max_length=255, verbose_name="达人名称")
avatar_url = models.TextField(blank=True, null=True, verbose_name="头像URL")
# 新增联系方式
email = models.EmailField(max_length=255, blank=True, null=True, verbose_name="电子邮箱")
instagram = models.CharField(max_length=255, blank=True, null=True, verbose_name="Instagram账号")
tiktok_link = models.URLField(max_length=255, blank=True, null=True, verbose_name="TikTok链接")
location = models.CharField(max_length=100, blank=True, null=True, verbose_name="位置")
live_schedule = models.CharField(max_length=255, blank=True, null=True, verbose_name="直播时间表")
# 类别 - Category
CATEGORY_CHOICES = [
('Phones & Electronics', '手机与电子产品'),
('Homes Supplies', '家居用品'),
('Kitchenware', '厨房用品'),
('Textiles & Soft Furnishings', '纺织品和软装'),
('Household Appliances', '家用电器'),
('Womenswear & Underwear', '女装和内衣'),
('Muslim Fashion', '穆斯林时尚'),
('Shoes', '鞋类'),
('Beauty & Personal Care', '美容和个人护理'),
('Computers & Office Equipment', '电脑和办公设备'),
('Pet Supplies', '宠物用品'),
('Baby & Maternity', '婴儿和孕妇用品'),
('Sports & Outdoor', '运动和户外'),
('Toys', '玩具'),
('Furniture', '家具'),
('Tools & Hardware', '工具和硬件'),
('Home Improvement', '家居装修'),
('Automotive & Motorcycle', '汽车和摩托车'),
('Fashion Accessories', '时尚配饰'),
('Food & Beverages', '食品和饮料'),
('Health', '健康'),
('Books, Magazines & Audio', '书籍、杂志和音频'),
('Kids Fashion', '儿童时尚'),
('Menswear & Underwear', '男装和内衣'),
('Luggage & Bags', '行李和包'),
('Pre-Owned Collections', '二手收藏'),
('Jewellery Accessories & Derivatives', '珠宝配饰及衍生品'),
]
category = models.CharField(max_length=100, choices=CATEGORY_CHOICES, blank=True, null=True, verbose_name="类别")
# 电商等级 - E-commerce Level (L1-L7)
E_COMMERCE_LEVEL_CHOICES = [
(1, 'L1'),
(2, 'L2'),
(3, 'L3'),
(4, 'L4'),
(5, 'L5'),
(6, 'L6'),
(7, 'L7'),
]
e_commerce_level = models.IntegerField(choices=E_COMMERCE_LEVEL_CHOICES, blank=True, null=True,
verbose_name="电商能力等级")
# 曝光等级 - Exposure Level (KOC-1, KOC-2, KOL-1, KOL-2, KOL-3)
EXPOSURE_LEVEL_CHOICES = [
('KOC-1', 'KOC-1'),
('KOC-2', 'KOC-2'),
('KOL-1', 'KOL-1'),
('KOL-2', 'KOL-2'),
('KOL-3', 'KOL-3'),
]
exposure_level = models.CharField(max_length=10, choices=EXPOSURE_LEVEL_CHOICES, blank=True, null=True,
verbose_name="曝光等级")
# 粉丝数 - Followers
followers = models.IntegerField(default=0, verbose_name="粉丝数")
# GMV - Gross Merchandise Value (in thousands of dollars)
gmv = models.DecimalField(max_digits=12, decimal_places=2, blank=True, null=True, verbose_name="GMV(千美元)")
items_sold = models.DecimalField(max_digits=12, decimal_places=2, blank=True, null=True,
verbose_name="售出商品数量")
# 视频数据 - Video Views
avg_video_views = models.IntegerField(default=0, blank=True, null=True, verbose_name="平均视频浏览量")
# 价格信息 - Pricing
pricing = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True, verbose_name="个人定价")
pricing_package = models.CharField(max_length=100, blank=True, null=True, verbose_name="套餐定价")
# 合作信息 - Collaboration
collab_count = models.IntegerField(default=0, blank=True, null=True, verbose_name="合作次数")
latest_collab = models.CharField(max_length=100, blank=True, null=True, verbose_name="最新合作")
# 电商平台 - E-commerce platforms (存储为JSON数组如["SUNLINK", "ARZOPA", "BELIFE"])
e_commerce_platforms = models.JSONField(blank=True, null=True, verbose_name="电商平台")
# 分析数据 - Analytics (JSON格式存储销售渠道和类别分布)
gmv_by_channel = models.JSONField(blank=True, null=True, verbose_name="GMV按渠道分布")
gmv_by_category = models.JSONField(blank=True, null=True, verbose_name="GMV按类别分布")
# MCN机构
mcn = models.CharField(max_length=255, blank=True, null=True, verbose_name="MCN机构")
# 时间戳
create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
update_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")
class Meta:
verbose_name = "达人信息"
verbose_name_plural = verbose_name
db_table = "creator_profiles"
def __str__(self):
return f"{self.name}"
class CreatorCampaign(models.Model):
"""达人-活动关联模型"""
creator = models.ForeignKey('CreatorProfile', on_delete=models.CASCADE, verbose_name="达人",
related_name="campaigns")
campaign = models.ForeignKey(BrandCampaign, on_delete=models.CASCADE, verbose_name="活动", related_name="creators")
status = models.CharField(max_length=20, default="pending", verbose_name="状态",
choices=[
("pending", "待处理"),
("accepted", "已接受"),
("rejected", "已拒绝"),
("completed", "已完成")
])
# 时间戳
create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
update_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")
class Meta:
verbose_name = "达人活动关联"
verbose_name_plural = verbose_name
db_table = "creator_campaigns"
unique_together = ('creator', 'campaign') # 一个达人在一个活动中只能有一条关联记录
def __str__(self):
return f"{self.creator.name} - {self.campaign.name}"
class BrandCampaign(models.Model):
"""品牌活动数据模型"""
BRAND_CHOICES = [
('U', 'U品牌'),
('R', 'R品牌'),
('X', 'X品牌'),
('Q', 'Q品牌'),
('A', 'A品牌'),
('M', 'M品牌'),
]
STATUS_CHOICES = [
('completed', '已完成'),
('in_progress', '进行中'),
('rejected', '已拒绝'),
]
brand_id = models.CharField(max_length=10, choices=BRAND_CHOICES, verbose_name="品牌ID")
brand_name = models.CharField(max_length=255, default="brand", verbose_name="品牌名称")
brand_color = models.CharField(max_length=20, default="#000000", verbose_name="品牌颜色")
# 添加关联到Campaign模型的外键
campaign = models.ForeignKey(BrandCampaign, on_delete=models.SET_NULL, null=True, blank=True, verbose_name="关联活动",
related_name="brand_campaigns")
pricing_detail = models.CharField(max_length=50, verbose_name="价格详情")
start_date = models.DateField(verbose_name="开始日期")
end_date = models.DateField(verbose_name="结束日期")
status = models.CharField(max_length=20, choices=STATUS_CHOICES, verbose_name="状态")
gmv_achieved = models.CharField(max_length=50, verbose_name="实现GMV")
views_achieved = models.CharField(max_length=50, verbose_name="实现观看量")
video_link = models.URLField(max_length=255, blank=True, null=True, verbose_name="视频链接")
# 时间戳
create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
update_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")
class Meta:
verbose_name = "品牌活动数据"
verbose_name_plural = verbose_name
db_table = "brand_campaigns"
def __str__(self):
return f"{self.brand_id} - {self.brand_name}"
class CreatorVideo(models.Model):
"""创作者视频模型,用于存储视频相关信息"""
# 关联字段
creator = models.ForeignKey('CreatorProfile', on_delete=models.CASCADE, related_name='videos')
# 视频基本信息
title = models.CharField(max_length=255, verbose_name="视频标题")
description = models.TextField(blank=True, null=True, verbose_name="视频描述")
thumbnail_url = models.URLField(max_length=500, blank=True, null=True, verbose_name="缩略图URL")
video_url = models.URLField(max_length=500, blank=True, null=True, verbose_name="视频URL")
video_id = models.CharField(max_length=100, verbose_name="视频ID")
# 视频类型
TYPE_CHOICES = [
('regular', '普通视频'),
('product', '带产品视频')
]
video_type = models.CharField(max_length=20, choices=TYPE_CHOICES, default='regular', verbose_name="视频类型")
# 视频标记
BADGE_CHOICES = [
('red', '红色标记'),
('gold', '金色标记')
]
badge = models.CharField(max_length=20, choices=BADGE_CHOICES, blank=True, null=True, verbose_name="视频标记")
# 视频统计
view_count = models.IntegerField(default=0, verbose_name="观看次数")
like_count = models.IntegerField(default=0, verbose_name="点赞数")
comment_count = models.IntegerField(default=0, verbose_name="评论数")
# 产品信息 (仅对带产品视频有效)
has_product = models.BooleanField(default=False, verbose_name="是否有产品")
product_name = models.CharField(max_length=255, blank=True, null=True, verbose_name="产品名称")
product_url = models.URLField(max_length=500, blank=True, null=True, verbose_name="产品链接")
# 发布信息
release_date = models.DateField(verbose_name="发布日期")
# 时间戳
created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")
class Meta:
verbose_name = "创作者视频"
verbose_name_plural = "创作者视频"
def __str__(self):
return f"{self.creator.name} - {self.title}"
class FollowerMetrics(models.Model):
"""粉丝统计数据模型"""
# 关联字段
creator = models.ForeignKey('CreatorProfile', on_delete=models.CASCADE, related_name='follower_metrics')
# 时间范围
start_date = models.DateField()
end_date = models.DateField()
# 粉丝性别统计
female_percentage = models.FloatField(default=0) # 女性百分比
male_percentage = models.FloatField(default=0) # 男性百分比
# 粉丝年龄分布
age_18_24_percentage = models.FloatField(default=0) # 18-24岁百分比
age_25_34_percentage = models.FloatField(default=0) # 25-34岁百分比
age_35_44_percentage = models.FloatField(default=0) # 35-44岁百分比
age_45_54_percentage = models.FloatField(default=0) # 45-54岁百分比
age_55_plus_percentage = models.FloatField(default=0) # 55+岁百分比
# 粉丝地域分布 (前5位)
location_data = models.JSONField(default=dict) # 格式: {"TX": 11, "FL": 8, "NY": 8, "GE": 5.5, "CA": 5}
# 创建和更新时间
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
verbose_name = '粉丝统计'
verbose_name_plural = '粉丝统计'
def __str__(self):
return f"{self.creator.name} 粉丝统计 ({self.start_date} - {self.end_date})"
class TrendMetrics(models.Model):
"""趋势统计数据模型"""
# 关联字段
creator = models.ForeignKey('CreatorProfile', on_delete=models.CASCADE, related_name='trend_metrics')
# 时间范围
date = models.DateField() # 数据日期
# 指标数据
gmv = models.FloatField(default=0) # GMV值
items_sold = models.IntegerField(default=0) # 销售商品数
followers_count = models.IntegerField(default=0) # 粉丝数
video_views = models.IntegerField(default=0) # 视频观看量
engagement_rate = models.FloatField(default=0) # 互动率(百分比)
# 创建和更新时间
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
verbose_name = '趋势指标'
verbose_name_plural = '趋势指标'
def __str__(self):
return f"{self.creator.name} 趋势指标 ({self.date})"
# 公有达人库
class PublicCreatorPool(models.Model):
"""公有达人库模型,存储系统提供的公共达人信息"""
creator = models.ForeignKey(CreatorProfile, on_delete=models.CASCADE, verbose_name="达人",
related_name="public_pool")
# is_active = models.BooleanField(default=True, verbose_name="是否活跃")
category = models.CharField(max_length=255, blank=True, null=True, verbose_name="分类")
remark = models.TextField(blank=True, null=True, verbose_name="备注")
# 时间戳
created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")
class Meta:
verbose_name = "公有达人库"
verbose_name_plural = verbose_name
db_table = "public_creator_pool"
def __str__(self):
return f"公有达人: {self.creator.name}"
# 私有达人库
class PrivateCreatorPool(models.Model):
"""私有达人库模型,用户可以将公有达人添加到自己的私有库中"""
user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="用户", related_name="private_creators", db_column='user_id')
name = models.CharField(max_length=255, verbose_name="私有库名称")
description = models.TextField(blank=True, null=True, verbose_name="描述")
is_default = models.BooleanField(default=False, verbose_name="是否为默认库")
# is_active = models.BooleanField(default=True, verbose_name="是否活跃")
# 时间戳
created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")
class Meta:
verbose_name = "私有达人库"
verbose_name_plural = verbose_name
db_table = "private_creator_pool"
unique_together = ('user', 'name') # 同一用户下不能有同名私有库
def __str__(self):
return f"{self.user.email}{self.name}"
# 私有达人库与达人的关联表
class PrivateCreatorRelation(models.Model):
"""私有达人库与达人的关联表,记录哪些达人被添加到了哪个私有库"""
private_pool = models.ForeignKey(PrivateCreatorPool, on_delete=models.CASCADE, verbose_name="私有达人库",
related_name="creator_relations")
creator = models.ForeignKey(CreatorProfile, on_delete=models.CASCADE, verbose_name="达人",
related_name="private_pool_relations")
added_from_public = models.BooleanField(default=True, verbose_name="是否从公有库添加")
notes = models.TextField(blank=True, null=True, verbose_name="笔记")
status = models.CharField(max_length=20, default="active", verbose_name="状态",
choices=[
("active", "活跃"),
("archived", "已归档"),
("favorite", "收藏")
])
# 时间戳
created_at = models.DateTimeField(auto_now_add=True, verbose_name="添加时间")
updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")
class Meta:
verbose_name = "私有库达人关联"
verbose_name_plural = verbose_name
db_table = "private_creator_relations"
unique_together = ('private_pool', 'creator') # 同一私有库中不能重复添加同一个达人
def __str__(self):
return f"{self.private_pool.name} - {self.creator.name}"