diff --git a/djangoblog/src/DjangoBlog-master/DjangoBlog-master/blog/management/commands/sync_user_avatar.py b/djangoblog/src/DjangoBlog-master/DjangoBlog-master/blog/management/commands/sync_user_avatar.py index d0f46127..6bade0d6 100644 --- a/djangoblog/src/DjangoBlog-master/DjangoBlog-master/blog/management/commands/sync_user_avatar.py +++ b/djangoblog/src/DjangoBlog-master/DjangoBlog-master/blog/management/commands/sync_user_avatar.py @@ -1,47 +1,86 @@ -import requests +import requests # 用于发送HTTP请求,验证图片URL有效性 from django.core.management.base import BaseCommand -from django.templatetags.static import static +from django.templatetags.static import static # 生成静态文件URL -from djangoblog.utils import save_user_avatar -from oauth.models import OAuthUser -from oauth.oauthmanager import get_manager_by_type +# 导入项目工具和模型:用户头像保存、OAuth用户模型、OAuth管理工具 +from djangoblog.utils import save_user_avatar # 保存用户头像到本地的工具函数 +from oauth.models import OAuthUser # OAuth关联用户模型(存储第三方登录用户信息) +from oauth.oauthmanager import get_manager_by_type # 根据 OAuth 类型获取对应管理器 class Command(BaseCommand): + """ + Django自定义管理命令:同步用户头像 + 用于检查并更新OAuth用户的头像URL,确保头像可访问(无效则重新获取或使用默认头像) + """ + # 命令的帮助信息(执行python manage.py help sync_user_avatar时显示) help = 'sync user avatar' def test_picture(self, url): + """ + 验证图片URL是否有效(可访问且返回200状态码) + :param url: 头像图片的URL + :return: 有效则返回True,否则返回False + """ try: + # 发送GET请求,超时2秒,检查状态码是否为200 if requests.get(url, timeout=2).status_code == 200: return True except: + # 任何异常(超时、连接错误等)均视为无效 pass + return False def handle(self, *args, **options): + """ + 命令核心执行逻辑 + 遍历所有OAuth用户,检查并同步头像URL + """ + # 获取项目静态文件的基础URL(用于判断头像是否为本地静态文件) static_url = static("../") + + # 获取所有OAuth用户 users = OAuthUser.objects.all() self.stdout.write(f'开始同步{len(users)}个用户头像') + + # 遍历每个用户处理头像 for u in users: - self.stdout.write(f'开始同步:{u.nickname}') - url = u.picture - if url: + self.stdout.write(f'开始同步:{u.nickname}') # 输出当前处理的用户名 + url = u.picture # 获取用户当前的头像URL + + if url: # 如果用户已有头像URL + # 情况1:头像URL是本地静态文件(以static_url开头) if url.startswith(static_url): + # 验证本地头像是否有效 if self.test_picture(url): - continue + self.stdout.write(f' 头像有效,跳过:{url}') + continue # 有效则跳过处理 else: - if u.metadata: + # 本地头像无效,尝试重新获取 + self.stdout.write(f' 本地头像无效,尝试重新获取') + if u.metadata: # 如果存在第三方平台返回的元数据(可能包含头像信息) + # 根据OAuth类型(如qq、weibo)获取对应的管理器 manage = get_manager_by_type(u.type) + # 从元数据中提取最新头像URL url = manage.get_picture(u.metadata) + # 保存头像到本地并返回新的URL url = save_user_avatar(url) else: + # 无元数据,使用默认头像 url = static('blog/img/avatar.png') else: + # 情况2:头像URL是第三方链接(非本地文件),保存到本地 + self.stdout.write(f' 第三方头像,保存到本地') url = save_user_avatar(url) else: + # 情况3:用户无头像URL,使用默认头像 + self.stdout.write(f' 无头像,使用默认头像') url = static('blog/img/avatar.png') + + # 更新用户头像并保存 if url: - self.stdout.write( - f'结束同步:{u.nickname}.url:{url}') + self.stdout.write(f' 结束同步:{u.nickname}.url:{url}') u.picture = url - u.save() - self.stdout.write('结束同步') + u.save() # 保存更新后的头像URL + + self.stdout.write('所有用户头像同步完成') \ No newline at end of file