TrainingPlatform_Django/datasets/models.py

321 lines
15 KiB
Python
Raw Permalink 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
import uuid
class CreatorProfile(models.Model):
"""达人信息模型,用于筛选功能"""
# 基本信息
name = models.CharField(max_length=255, verbose_name="达人名称")
# 修改为支持本地图片上传同时保持URL兼容性
avatar = models.ImageField(upload_to='avatars/', blank=True, null=True, verbose_name="头像图片")
avatar_url = models.TextField(blank=True, null=True, verbose_name="头像URL")
platform_id = models.CharField(max_length=255, blank=True, null=True, verbose_name="Platform ID")
# 新增联系方式
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账号")
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="直播时间表")
# 新增达人平台字段
PROFILE_CHOICES = [
('tiktok', 'TikTok'),
('instagram', 'Instagram'),
('youtube', 'YouTube'),
('other', '其他平台'),
]
profile = models.CharField(max_length=20, choices=PROFILE_CHOICES, default='tiktok', verbose_name="达人平台")
# 新增hashtag和trend字段
hashtags = models.TextField(blank=True, null=True, verbose_name="标签", help_text="以#分隔的标签,例如:#fashion#beauty#lifestyle")
trends = models.TextField(blank=True, null=True, verbose_name="趋势", help_text="创作者相关的趋势关键词")
# 新增地区字段
region = models.CharField(max_length=100, blank=True, null=True, verbose_name="地区")
# 新增主页链接字段
tiktok_link = models.URLField(max_length=500, blank=True, null=True, verbose_name="主页链接")
# 新增对标美区达人等级
us_creator_level = models.CharField(max_length=50, blank=True, null=True, verbose_name="对标美区达人等级")
# 新增报价字段
price_gbp = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True, verbose_name="报价(英镑)")
price_usd = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True, verbose_name="报价(美金)")
# 新增GMV(英镑)字段
gmv_gbp = models.DecimalField(max_digits=12, decimal_places=2, blank=True, null=True, verbose_name="GMV(英镑)")
# 新增链接字段
link = models.URLField(max_length=500, 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="更新时间")
def get_avatar_url(self):
"""获取头像URL优先返回本地图片其次返回外部URL"""
if self.avatar:
return self.avatar.url
elif self.avatar_url:
return self.avatar_url
return None
class Meta:
verbose_name = "达人信息"
verbose_name_plural = verbose_name
db_table = "creator_profiles"
def __str__(self):
return f"{self.name}"
class Brand(models.Model):
"""品牌模型"""
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=100, unique=True, verbose_name='品牌名称')
description = models.TextField(blank=True, null=True, verbose_name='品牌描述')
logo_url = models.CharField(max_length=255, blank=True, null=True, verbose_name='品牌Logo')
category = models.CharField(max_length=100, blank=True, null=True, verbose_name='品牌分类')
source = models.CharField(max_length=100, blank=True, null=True, verbose_name='来源')
collab_count = models.IntegerField(default=0, verbose_name='合作数量')
creators_count = models.IntegerField(default=0, verbose_name='创作者数量')
campaign_id = models.CharField(max_length=100, blank=True, null=True, verbose_name='活动ID')
# 添加数据统计字段
total_gmv_achieved = models.DecimalField(max_digits=12, decimal_places=2, default=0, verbose_name='总GMV')
total_views_achieved = models.DecimalField(max_digits=12, decimal_places=2, default=0, verbose_name='总浏览量')
shop_overall_rating = models.DecimalField(max_digits=3, decimal_places=1, default=0.0, verbose_name='店铺评分')
# 存储关联到此品牌的所有产品和活动知识库ID列表
dataset_id_list = models.JSONField(default=list, blank=True, verbose_name='知识库ID列表',
help_text='所有关联的知识库ID列表')
created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')
is_active = models.BooleanField(default=True, verbose_name='是否激活')
class Meta:
verbose_name = '品牌'
verbose_name_plural = '品牌'
def __str__(self):
return self.name
class Product(models.Model):
"""产品模型 - 作为一个知识库"""
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
brand = models.ForeignKey(Brand, on_delete=models.CASCADE, related_name='products', verbose_name='所属品牌')
name = models.CharField(max_length=100, verbose_name='产品名称')
description = models.TextField(blank=True, null=True, verbose_name='产品描述')
image_url = models.CharField(max_length=255, blank=True, null=True, verbose_name='产品图片')
# 添加产品详情字段
pid = models.CharField(max_length=100, blank=True, null=True, verbose_name='产品ID')
commission_rate = models.DecimalField(max_digits=5, decimal_places=2, default=0, verbose_name='佣金率')
open_collab = models.DecimalField(max_digits=5, decimal_places=2, default=0, verbose_name='开放合作率')
available_samples = models.IntegerField(default=0, verbose_name='可用样品数')
sales_price_min = models.DecimalField(max_digits=10, decimal_places=2, default=0, verbose_name='最低销售价')
sales_price_max = models.DecimalField(max_digits=10, decimal_places=2, default=0, verbose_name='最高销售价')
stock = models.IntegerField(default=0, verbose_name='库存')
items_sold = models.IntegerField(default=0, verbose_name='已售数量')
product_rating = models.DecimalField(max_digits=3, decimal_places=1, default=0, verbose_name='产品评分')
reviews_count = models.IntegerField(default=0, verbose_name='评价数量')
collab_creators = models.IntegerField(default=0, verbose_name='合作创作者数')
tiktok_shop = models.BooleanField(default=False, verbose_name='是否TikTok商店')
dataset_id = models.CharField(max_length=100, blank=True, null=True, verbose_name='知识库ID',
help_text='外部知识库系统中的ID')
external_id = models.CharField(max_length=100, blank=True, null=True, verbose_name='外部ID',
help_text='外部系统中的唯一标识')
created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')
is_active = models.BooleanField(default=True, verbose_name='是否激活')
creators = models.ManyToManyField(
'CreatorProfile',
through='CreatorProductMatch',
related_name='matched_products',
verbose_name='匹配达人'
)
class Meta:
verbose_name = '产品'
verbose_name_plural = '产品'
unique_together = ['brand', 'name']
indexes = [
models.Index(fields=['brand']),
models.Index(fields=['dataset_id']),
models.Index(fields=['is_active']),
models.Index(fields=['pid']),
]
def __str__(self):
return f"{self.brand.name} - {self.name}"
def save(self, *args, **kwargs):
"""重写save方法更新品牌的dataset_id_list"""
is_new = self.pk is None
super().save(*args, **kwargs)
# 刷新品牌的dataset_id_list
if is_new and self.is_active and self.dataset_id:
brand = self.brand
if self.dataset_id not in brand.dataset_id_list:
brand.dataset_id_list.append(self.dataset_id)
brand.save(update_fields=['dataset_id_list', 'updated_at'])
class CreatorProductMatch(models.Model):
creator = models.ForeignKey('CreatorProfile', on_delete=models.CASCADE, verbose_name='达人')
product = models.ForeignKey('Product', on_delete=models.CASCADE, verbose_name='产品')
is_matched = models.BooleanField(default=False, verbose_name='是否匹配')
match_score = models.FloatField(blank=True, null=True, verbose_name='匹配度分数')
class Meta:
unique_together = ('creator', 'product')
verbose_name = '达人-产品匹配'
verbose_name_plural = verbose_name
def __str__(self):
return f"{self.creator} - {self.product} 匹配: {self.is_matched} 分数: {self.match_score}"
class Dataset(models.Model):
# 自增主键字段Django 默认为每个模型提供一个 id 字段
# 但是如果你需要自定义主键字段,可以用 `primary_key=True` 显式声明
id = models.AutoField(primary_key=True) # 自增主键
# 数据集名称最长255个字符不能为空
name = models.CharField(max_length=255)
# 创建该数据集的用户最长100个字符不能为空
user = models.CharField(max_length=100)
# 任务类型最长50个字符不能为空
task_type = models.CharField(max_length=16)
# 数据集大小使用BigIntegerField来表示较大的整数
size = models.CharField(max_length=64)
# 数据集的总图片数
number = models.IntegerField()
#数据集的描述
description = models.TextField(default="")
# 创建时间,默认为当前时间戳
create_time = models.DateTimeField(auto_now_add=True) # 自动设置为当前时间(只在创建时)
# 数据集的类别,使用 JSONField 存储类别信息
categories = models.JSONField(default=list) # 默认值为一个空列表
# 该数据集是否上传至minio的一个标识
is_upload = models.BooleanField(default=False) # 表示数据集是否已上传,默认为 False
def update_is_upload(self, upload_status):
"""更新数据集的上传状态"""
self.is_upload = upload_status
self.save() # 保存更改到数据库
def __str__(self):
return self.name # 返回数据集名称作为对象的字符串表示
class Project(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=255)
user = models.CharField(max_length=100)
task_type = models.CharField(max_length=16)
description = models.TextField(default="")
create_time = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name