优化过滤

This commit is contained in:
jlj 2025-06-06 15:15:28 +08:00
parent b554cbf8d2
commit 32d09a9ac7
2 changed files with 174 additions and 167 deletions

View File

@ -3300,10 +3300,32 @@ def filter_private_pool_creators(request):
'message': f'找不到ID为 {pool_id} 的私有库',
'data': None
}, json_dumps_params={'ensure_ascii': False})
else:
# 当不提供pool_id时需要去除重复的达人
# 使用distinct('creator')获取不重复的达人关系
# 由于Django ORM的限制我们需要在内存中进行去重
seen_creator_ids = set()
unique_relations = []
# 先获取所有符合条件的关系
all_relations = list(creator_relations)
# 在内存中去重只保留每个creator_id的第一条记录
for relation in all_relations:
if relation.creator.id not in seen_creator_ids:
seen_creator_ids.add(relation.creator.id)
unique_relations.append(relation)
# 使用去重后的关系列表
creator_relations = unique_relations
# 应用状态过滤条件仅当提供了status参数时
if status:
if pool_id:
creator_relations = creator_relations.filter(status=status)
else:
# 在内存中进行过滤
creator_relations = [relation for relation in creator_relations if relation.status == status]
# 应用复杂过滤条件
# --------- 从filter_creators借鉴的过滤逻辑 ---------
@ -3311,7 +3333,12 @@ def filter_private_pool_creators(request):
# Category 多选过滤
category = filter_data.get('category')
if category and len(category) > 0:
if pool_id:
creator_relations = creator_relations.filter(creator__category__in=category)
else:
# 在内存中过滤
creator_relations = [relation for relation in creator_relations
if relation.creator.category in category]
# 电商能力等级过滤 (L1-L7),多选
e_commerce_level = filter_data.get('e_commerce_level')
@ -3321,21 +3348,37 @@ def filter_private_pool_creators(request):
if level_str.startswith('L'):
level_nums.append(int(level_str[1:]))
if level_nums:
if pool_id:
creator_relations = creator_relations.filter(creator__e_commerce_level__in=level_nums)
else:
# 在内存中过滤
creator_relations = [relation for relation in creator_relations
if relation.creator.e_commerce_level in level_nums]
# 曝光等级过滤 (KOL-1, KOL-2, KOC-1等),多选
exposure_level = filter_data.get('exposure_level')
if exposure_level and len(exposure_level) > 0:
if pool_id:
creator_relations = creator_relations.filter(creator__exposure_level__in=exposure_level)
else:
# 在内存中过滤
creator_relations = [relation for relation in creator_relations
if relation.creator.exposure_level in exposure_level]
# 平台过滤tiktok, instagram, youtube等单选
platform = filter_data.get('platform')
if platform and platform:
if pool_id:
creator_relations = creator_relations.filter(creator__profile=platform)
else:
# 在内存中过滤
creator_relations = [relation for relation in creator_relations
if relation.creator.profile == platform]
# GMV范围过滤 ($0-$5k, $5k-$25k, $25k-$50k等),多选
gmv_range = filter_data.get('gmv_range')
if gmv_range and len(gmv_range) > 0:
if pool_id:
gmv_q = Q()
for gmv_val in gmv_range:
gmv_min, gmv_max = 0, float('inf')
@ -3362,6 +3405,32 @@ def filter_private_pool_creators(request):
gmv_q |= range_q
creator_relations = creator_relations.filter(gmv_q)
else:
# 在内存中过滤
filtered_relations = []
for relation in creator_relations:
creator_gmv = relation.creator.gmv or 0
for gmv_val in gmv_range:
gmv_min, gmv_max = 0, float('inf')
if gmv_val == "$0-$5k":
gmv_min, gmv_max = 0, 5
elif gmv_val == "$5k-$25k":
gmv_min, gmv_max = 5, 25
elif gmv_val == "$25k-$50k":
gmv_min, gmv_max = 25, 50
elif gmv_val == "$50k-$150k":
gmv_min, gmv_max = 50, 150
elif gmv_val == "$150k-$400k":
gmv_min, gmv_max = 150, 400
elif gmv_val == "$400k-$1500k":
gmv_min, gmv_max = 400, 1500
elif gmv_val == "$1500k+":
gmv_min, gmv_max = 1500, float('inf')
if gmv_min <= creator_gmv <= gmv_max:
filtered_relations.append(relation)
break
creator_relations = filtered_relations
# 观看量范围过滤,使用数值数组格式
views_range = filter_data.get('views_range')
@ -3369,10 +3438,19 @@ def filter_private_pool_creators(request):
views_min = views_range[0]
views_max = views_range[1]
if pool_id:
if views_min is not None:
creator_relations = creator_relations.filter(creator__avg_video_views__gte=views_min)
if views_max is not None:
creator_relations = creator_relations.filter(creator__avg_video_views__lte=views_max)
else:
# 在内存中过滤
filtered_relations = []
for relation in creator_relations:
views = relation.creator.avg_video_views or 0
if (views_min is None or views >= views_min) and (views_max is None or views <= views_max):
filtered_relations.append(relation)
creator_relations = filtered_relations
# 价格区间过滤逻辑,使用数值数组格式
pricing = filter_data.get('pricing')
@ -3380,19 +3458,31 @@ def filter_private_pool_creators(request):
min_price = pricing[0]
max_price = pricing[1]
if pool_id:
if min_price is not None:
creator_relations = creator_relations.filter(creator__pricing__gte=min_price)
if max_price is not None:
creator_relations = creator_relations.filter(creator__pricing__lte=max_price)
else:
# 在内存中过滤
filtered_relations = []
for relation in creator_relations:
price = relation.creator.pricing or 0
if (min_price is None or price >= min_price) and (max_price is None or price <= max_price):
filtered_relations.append(relation)
creator_relations = filtered_relations
# 获取总数据量
total_count = creator_relations.count()
total_count = len(creator_relations) if not pool_id else creator_relations.count()
# 计算分页
start = (page - 1) * page_size
end = start + page_size
# 执行查询并分页
if pool_id:
paged_relations = creator_relations[start:end]
else:
paged_relations = creator_relations[start:end]
creator_list = []
@ -3785,11 +3875,18 @@ def search_private_creators(request):
page = int(request.GET.get('page', 1))
page_size = int(request.GET.get('page_size', 10))
# 获取pool_id参数如果提供了则只搜索特定库
pool_id = request.GET.get('pool_id')
# 直接搜索用户所有私有库中的达人
query = PrivateCreatorRelation.objects.filter(
private_pool__user=user
).select_related('creator', 'private_pool')
# 如果提供了pool_id则只搜索特定私有库
if pool_id:
query = query.filter(private_pool_id=pool_id)
# 如果有搜索关键词,进行模糊搜索
if search_query:
# 分割关键词(支持空格、逗号、分号分隔)
@ -3878,6 +3975,32 @@ def search_private_creators(request):
# 如果没有搜索词,按名称排序
query = query.order_by('creator__name')
# 当不提供pool_id时进行达人去重
if not pool_id:
# 先获取所有符合条件的关系
all_relations = list(query)
# 在内存中去重只保留每个creator_id的第一条记录
seen_creator_ids = set()
unique_relations = []
for relation in all_relations:
if relation.creator.id not in seen_creator_ids:
seen_creator_ids.add(relation.creator.id)
unique_relations.append(relation)
# 使用去重后的关系列表
relations = unique_relations
total_count = len(relations)
# 计算分页
start = (page - 1) * page_size
end = min(start + page_size, total_count)
# 执行分页
private_creator_relations = relations[start:end]
else:
# 如果提供了pool_id不需要去重直接使用数据库查询
# 获取总数据量
total_count = query.count()
@ -3953,7 +4076,8 @@ def search_private_creators(request):
"results_count": total_count,
"search_applied": bool(search_query),
"supports_single_char": True, # 标识支持单字符搜索
"search_scope": "private_only" # 标识只搜索私有达人库
"search_scope": "private_only", # 标识只搜索私有达人库
"is_deduplicated": not pool_id # 标识是否进行了达人去重
}
return JsonResponse({

View File

@ -1,117 +0,0 @@
#!/usr/bin/env python
"""
测试达人头像显示功能
演示如何使用本地图片和外部URL
"""
import os
import django
# 设置Django环境
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'daren.settings')
django.setup()
from apps.daren_detail.models import CreatorProfile
from django.core.files import File
from django.core.files.uploadedfile import SimpleUploadedFile
def test_avatar_display():
"""测试头像显示功能"""
print("=== 达人头像显示功能测试 ===\n")
# 1. 查询现有达人
creators = CreatorProfile.objects.all()[:3]
print("1. 现有达人头像状态:")
for creator in creators:
avatar_url = creator.get_avatar_url()
has_local = bool(creator.avatar)
has_external = bool(creator.avatar_url)
print(f" - {creator.name}:")
print(f" 本地图片: {'' if has_local else ''}")
print(f" 外部URL: {'' if has_external else ''}")
print(f" 显示URL: {avatar_url or ''}")
print()
# 2. 演示URL访问方式
print("2. 头像URL访问示例")
for creator in creators:
avatar_url = creator.get_avatar_url()
if avatar_url:
if creator.avatar:
print(f" 本地图片: http://localhost:8000{avatar_url}")
else:
print(f" 外部URL: {avatar_url}")
else:
print(f" {creator.name}: 无头像")
print()
# 3. 创建测试数据示例
print("3. 创建测试达人示例:")
# 示例1仅外部URL
creator1, created = CreatorProfile.objects.get_or_create(
name="测试达人A",
defaults={
'avatar_url': 'https://example.com/avatar1.jpg',
'category': 'Beauty & Personal Care',
'followers': 1000
}
)
print(f" - {creator1.name}: {creator1.get_avatar_url()}")
# 示例2仅本地图片如果存在的话
existing_avatar = CreatorProfile.objects.filter(avatar__isnull=False).first()
if existing_avatar:
print(f" - {existing_avatar.name}: {existing_avatar.get_avatar_url()}")
print("\n=== 前端使用示例代码 ===")
print("""
// JavaScript: 获取并显示头像
fetch('/api/daren_detail/creators/')
.then(response => response.json())
.then(data => {
data.results.forEach(creator => {
if (creator.avatar_display_url) {
console.log(`${creator.name}: ${creator.avatar_display_url}`);
// 创建图片元素
const img = document.createElement('img');
img.src = creator.avatar_display_url;
img.alt = `${creator.name}的头像`;
img.className = 'creator-avatar';
// 添加到页面
document.getElementById('creators-list').appendChild(img);
}
});
});
""")
print("\n=== HTML模板使用示例 ===")
print("""
<!-- Django模板中使用 -->
{% for creator in creators %}
<div class="creator-card">
<h3>{{ creator.name }}</h3>
{% if creator.get_avatar_url %}
<img src="{{ creator.get_avatar_url }}"
alt="{{ creator.name }}的头像"
class="avatar">
{% else %}
<div class="no-avatar">暂无头像</div>
{% endif %}
</div>
{% endfor %}
""")
if __name__ == "__main__":
try:
test_avatar_display()
except Exception as e:
print(f"测试出错: {e}")
print("请确保:")
print("1. 已运行 python manage.py migrate")
print("2. 数据库中有达人数据")
print("3. media/avatars/ 目录存在")