day13-Trae之一键换脸APP开发03
今日内容
1 后端Django项目
trae或者其他ai工具去编写项目时---》如果UI图不一样,写出来的,可能跟我的不一样
后端的代码,前端代码,每次写都会有差距
Django后端项目---》Python的一个web框架----》学习成本挺高---》学习周期建议1个月
我们没有学习,里面好多东西不懂---》我们尽量全部使用trae生成
目前使用trae完全基于一个空文件夹创建的这个项目---》这个项目之前不存在
1.0 trae token超长问题
# 写小型项目不会有问题
# 中大型项目---》输入提示词---》模型思考次数已达上限,请输入“继续”后获得更多结果---》只有输入继续让它继续做
# 有可能,会把之前写完了,又做了一点改动
- 这个我们不用管---》完全交个Trae即可
1.1 表迁移和创建管理员用户
根据项目需求:@项目需求.md 和项目后端架构文档:@1-项目后端架构文档.md ,生成换脸app后台Django的项目和代码
要求:
1.项目写入到目录change_face_api中。
2.生成相关表模型,写入到每个app的models中。
3.生成所有接口,并能正常调用。
4.链接数据库地址为:
-host:127.0.0.1
-port:3307
-database:change_face
-user:root
-password:lqz123?
5.Django 后台admin使用django-simpleui美化,项目做好本地化和时区设置。
6.换脸功能对接Coze一键换脸工作流:API_KEY和工作流ID暂时为空,对接方案参照:
-执行工作流:https://www.coze.cn/open/docs/developer_guides/workflow_run
-查询工作流执行结果:https://www.coze.cn/open/docs/developer_guides/workflow_history
# 1 如图下三个命令,如果出现---》我们需要跟它交互
-Django项目独有
# 2 python manage.py makemigrations
-我们只创建了数据库的库:change_face
-但是没有表:比如:存用户信息的用户表,换脸记录的换脸表
-Trae写了代码---》使用命令:python manage.py makemigrations--》把表创建到数据库中:change_face
-在change_face这个库中创建出表:如果只执行makemigrations--》生成要创建表的记录
# 3 python manage.py migrate
-就会把表创建到 数据库中--》我们就能看到很多表了--》如下图
-表里没有记录:没数据
-控制台如下图:会有建表的输出---》绿色ok的样子
# 4 python manage.py createsuperuser
-向用户表中创建一条记录
-app登录的时候,可以使用这个用户
-后端的后台管理,需要使用这个账号登录
-需要再控制台交互---》输入用户名密码邮箱--》如下图
-只需要输入密码:输入两次--》密码简单--》需要再输入y
-用户名是:admin :自己写了
-邮箱是:admin@example.com
1.2 启动项目(注意路径)
# 1 trae 写完后端,会运行,让我们查看--》执行下面那个命令
-python manage.py runserver 0.0.0.0:8000
# 2 我们再浏览器中输入:http://127.0.0.1:8000/admin/
-就能看到后端的后台管理
-管理用户
-查看用户的换脸记录
。。。。
# 3 启动后端服务
-方式一:直接使用提示词让它启动
帮我启动后端到0.0.0.0:8000上
-方式二:我们自己在控制台使用命令启动,需要注意目录:一定要切到后端项目所在目录
-python manage.py runserver 0.0.0.0:8000
# 4 关闭后端服务
ctrl+c # 要在命令窗口下敲
1.4 项目能启动
#1 后端项目如果能顺利运行,没报错
-后端项目已经写的差不多了
-但是多半对接coze工作流会有问题---》我们先不调--》对接app时再调
-只要能访问到后台管理:http://127.0.0.1:8000/admin/ 后端就告一段落
# 2 有的同学,提示词输入后,生成的djagno项目,可能运行报错
-使用提示词,让trae它自己去修复
-1 你检查整个后端项目,把存在的问题都解决
-2 后端项目换脸功能,存在问题,帮我检查,并修复
-3 把控制台的报错,复制粘贴
项目报错如下,帮我修复:粘贴的错误
。。。。。。
# 3 我们一定要清楚
我们 -----》 Trae之间
需要使用 提示词 来交互
如果它改的不是你想要的---》一定是你没描述清楚---》尽可能详细的去描述
1.3 对接coze工作流问题--对接app时再解决
2 编写APP端代码
2.0 把我们之前使用Androidstudio创建的项目复制到我们Trae目录下
# 在Androidstudio上右键项目---》copy path --》absoloate path---》复制
-把Change_face 项目整个copy
-到 我们Trae项目的目录下
2.1 提示词
根据项目需求:和项目APP架构文档:和UI设计图: 生成智能换脸app端代码
要求:
1.我已经创建了APP端项目: ,你在这个基础上继续编写,只给我修改代码部分,gradle和java配置尽量不动。
2.根据需求帮编写完安卓app端代码。
3.接口参考后端项目: ,并正常测试通过,前后端调通。
4.后端链接地址为:http://127.0.0.1:8000,注意安卓端使用http链接权限问题。
5.APP端使用原生java11开发,gradle版本为8.13,我已经设置好,尽量不要动配置。
6.APP端不联网,也能顺利运行。
7.仔细查看后端接口返回格式,注意前后端对接格式。
# 经过漫长等待---》app端项目写完了
# 接下来,要让app装到手机上
# 使用提示词
帮我把app端,编译,并安装到我手机上
# 由于Trae帮我们写的app程序,存在问题
# 不需要我们动手---》它会自动检查错误---》自动修复--》这个过程或时间,不确定
-全部接受
# 它还是改了 gradle和java版本
# 电脑关机了,再开机--》继续输入提示词,让它修复即可
# 我们现在顺着它来--》由于有错--》app编译不了
-1 帮我检查app端代码的错误并修复,能够运行
-2 使用Androidstudio打开我们正在编写的项目
-注意,不是之前的项目,之前项目还是空的
-点击绿色箭头,安装到手机上
-由于有错:错误会在控制台显示
-3 app端报错如下,帮我修复:错误粘贴
2.2 编译安装app
# 在命令行中运行,注意路径
cd Change_Face
.\gradlew build
.\gradlew clean assembleDebug
.\gradlew installDebug
3 前后端联调-纠错
3.1 后端coze 工作流问题
3.1.1 对接测试脚本--》调通了
# 1 我们需要把这个测试脚本,放到项目中
# 2 我已经把后端对接coze换脸工作流的测试脚本写好了,你参照:,帮我修复后端对接的错误
import time
import logging
import os
import requests
import argparse
import json
import time
# 配置日志
def setup_logger():
# 设置为DEBUG级别以获取更详细的日志
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
return logging.getLogger('coze_test')
# 设置requests库的日志级别为WARNING,避免打印过多的HTTP请求细节
logging.getLogger('urllib3').setLevel(logging.WARNING)
# 创建日志目录
def ensure_log_directory():
log_dir = os.path.join(os.getcwd(), 'test_logs')
os.makedirs(log_dir, exist_ok=True)
return log_dir
# 保存详细日志到文件
def save_detailed_log(log_data):
log_dir = ensure_log_directory()
timestamp = int(time.time())
log_file = os.path.join(log_dir, f'coze_test_{timestamp}.json')
with open(log_file, 'w', encoding='utf-8') as f:
json.dump(log_data, f, ensure_ascii=False, indent=2)
return log_file
class CozeWorkflowTester:
def __init__(self, api_key, workflow_id, base_url='https://api.coze.cn'):
self.api_key = api_key
self.workflow_id = workflow_id
self.base_url = base_url
self.headers = {
'Authorization': f'Bearer {self.api_key}',
'Content-Type': 'application/json'
}
self.file_upload_endpoint = f"{self.base_url}/v1/files/upload"
self.workflow_endpoint = f"{self.base_url}/v1/workflow/run"
# 根据用户提供的正确接口,使用参数化URL格式
self.task_status_endpoint_template = "{base_url}/v1/workflows/{workflow_id}/run_histories/{execute_id}"
self.logger = setup_logger()
def upload_file(self, file_path):
"""上传文件到Coze并获取文件ID"""
if not os.path.exists(file_path):
raise FileNotFoundError(f"文件不存在: {file_path}")
try:
self.logger.info(f"开始上传文件: {file_path}")
# 构建请求头,不包含Content-Type,让requests自动处理
upload_headers = {
'Authorization': f'Bearer {self.api_key}'
}
# 读取文件并准备上传
with open(file_path, 'rb') as f:
files = {'file': (os.path.basename(file_path), f)}
# 发送请求
response = requests.post(
url=self.file_upload_endpoint,
headers=upload_headers,
files=files
)
# 记录请求和响应
self.logger.info(f"文件上传响应状态: {response.status_code}")
self.logger.debug(f"文件上传响应内容: {response.text}")
# 解析响应
result = response.json()
# 检查是否成功
if response.status_code == 200 and 'data' in result and result.get('code') == 0:
file_id = result['data'].get('id')
if file_id:
self.logger.info(f"文件上传成功,文件ID: {file_id}")
return file_id
else:
self.logger.error(f"无法从响应中提取文件ID: {result}")
raise Exception(f"无法从响应中提取文件ID: {result}")
else:
self.logger.error(f"文件上传失败: {result}")
raise Exception(f"文件上传失败: {result}")
except Exception as e:
self.logger.error(f"文件上传异常: {str(e)}")
raise
def run_workflow(self, source_image_path, target_image_path):
"""运行Coze工作流"""
try:
# 先上传图片获取文件ID
source_file_id = self.upload_file(source_image_path)
target_file_id = self.upload_file(target_image_path)
# 尝试修改app_id和is_async参数,使用更简单的参数名称
# 1. 设置app_id为workflow_id(这是一种尝试)
# 2. 将is_async设置为True
# 3. 使用最简单的参数名称
# 改回之前成功的格式:使用face、backed和text参数,file_id为字符串形式的JSON
import json
payload = {
"workflow_id": self.workflow_id,
"parameters": {
"face": json.dumps({"file_id": source_file_id}),
"backed": json.dumps({"file_id": target_file_id}),
"text": "执行换脸操作"
},
"app_id": "",
"is_async": True
}
self.logger.info(f"正在调用Coze工作流,ID: {self.workflow_id}")
# 发送请求
response = requests.post(
self.workflow_endpoint,
headers=self.headers,
json=payload
)
# 准备详细日志数据
log_data = {
'timestamp': time.strftime('%Y-%m-%d %H:%M:%S'),
'workflow_id': self.workflow_id,
'request': {
'url': self.workflow_endpoint,
'headers': self.headers,
'payload': payload
},
'response': {
'status_code': response.status_code,
'headers': dict(response.headers),
'content': response.text
}
}
# 保存日志到文件
log_file = save_detailed_log(log_data)
self.logger.info(f"详细日志已保存到: {log_file}")
# 检查响应
if response.status_code != 200:
error_msg = f"工作流调用失败,状态码: {response.status_code}, 响应: {response.text}"
self.logger.error(error_msg)
raise Exception(error_msg)
# 解析响应
try:
result = response.json()
except json.JSONDecodeError:
error_msg = f"无法解析响应JSON: {response.text}"
self.logger.error(error_msg)
raise Exception(error_msg)
# 根据用户提示,正确的任务ID提取方式应该是检查msg为Success和提取execute_id
# 检查响应消息是否成功
if result.get('code') == 0 or result.get('msg') == '':
# 提取execute_id作为任务ID
task_id = result.get('execute_id')
if task_id:
self.logger.info(f"工作流调用成功,任务ID: {task_id}")
return task_id
else:
error_msg = f"msg为Success但未找到execute_id: {result}"
self.logger.error(error_msg)
raise Exception(error_msg)
else:
error_msg = f"工作流调用失败,返回消息: {result.get('msg')},详情: {result}"
self.logger.error(error_msg)
raise Exception(error_msg)
except Exception as e:
self.logger.error(f"工作流调用异常: {str(e)}")
raise
def get_workflow_result(self, task_id):
"""获取工作流执行结果"""
try:
self.logger.info(f"正在查询任务结果,ID: {task_id}")
# 使用用户提供的正确接口URL格式: https://api.coze.cn/v1/workflows/:workflow_id/run_histories/:execute_id
# 构建完整的任务状态查询URL
task_status_endpoint = self.task_status_endpoint_template.format(
base_url=self.base_url,
workflow_id=self.workflow_id,
execute_id=task_id
)
# 发送GET请求获取任务状态,新接口使用GET而不是POST
response = requests.get(
task_status_endpoint,
headers=self.headers
)
# 检查响应
if response.status_code != 200:
self.logger.error(f"查询结果失败,状态码: {response.status_code}, 响应: {response.text}")
raise Exception(f"查询结果失败: {response.status_code} - {response.text}")
# 解析响应
result = response.json()
# 根据用户要求,只要code为0表示成功,返回的数据在data中
# 检查任务状态
code = result.get('code')
if code == 0:
# 任务成功完成
# 获取data中的结果数据
data = result.get('data', {})[0]
execute_status = data.get('execute_status','')
if execute_status == 'Success':
self.logger.info(f"-----------------------: {data.get('output')}")
result_image_url = json.loads(json.loads(data.get('output')).get('Output')).get('output')
if result_image_url:
self.logger.info(f"结果图片URL: {result_image_url}")
# 下载结果图片到本地
local_path = self.download_image(result_image_url, task_id)
return {
'status': 'success',
'result_image_url': result_image_url,
'local_image_path': local_path,
'processing_time': result.get('processing_time', 0),
'task_id': task_id
}
else:
return {
'status': 'success',
'message': '任务成功但未返回图片',
'task_id': task_id
}
elif execute_status == 'Fail':
# 任务失败
self.logger.error(f"任务执行失败")
return {
'status': 'failed',
'error_message': '任务执行失败',
'task_id': task_id
}
else:
# 任务仍在处理中
self.logger.info(f"任务处理中,状态: {execute_status}")
return {
'status': 'processing',
'task_id': task_id
}
else:
error_msg = f"查询结果失败,返回消息: {result.get('msg')},详情: {result}"
self.logger.error(error_msg)
raise Exception(error_msg)
except Exception as e:
self.logger.error(f"查询结果异常: {str(e)}")
raise
def download_image(self, image_url, task_id):
"""下载图片到本地"""
try:
# 创建保存目录
result_dir = os.path.join(os.getcwd(), 'coze_results')
os.makedirs(result_dir, exist_ok=True)
# 生成保存路径
image_filename = f"result_{task_id}_{int(time.time())}.jpg"
save_path = os.path.join(result_dir, image_filename)
# 下载图片
self.logger.info(f"正在下载图片: {image_url}")
response = requests.get(image_url, stream=True)
response.raise_for_status()
# 保存图片
with open(save_path, 'wb') as f:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)
self.logger.info(f"图片已保存到: {save_path}")
return save_path
except Exception as e:
self.logger.error(f"图片下载失败: {str(e)}")
return None
def test_workflow(self, source_image_path, target_image_path):
"""完整测试工作流"""
try:
# 运行工作流
task_id = self.run_workflow(source_image_path, target_image_path)
# 轮询结果,最多等待120秒
max_wait_time = 120
wait_interval = 5
elapsed_time = 0
while elapsed_time < max_wait_time:
result = self.get_workflow_result(task_id)
if result['status'] == 'success':
print(f"\n测试成功!")
print(f"任务ID: {result['task_id']}")
print(f"处理时间: {result.get('processing_time', '未知')}秒")
print(f"结果图片URL: {result.get('result_image_url', '无')}")
print(f"本地保存路径: {result.get('local_image_path', '无')}")
return True
elif result['status'] == 'failed':
print(f"\n测试失败!")
print(f"任务ID: {result['task_id']}")
print(f"错误信息: {result.get('error_message', '未知错误')}")
return False
# 等待一段时间后重试
print(f"任务处理中,{wait_interval}秒后再次查询...")
time.sleep(wait_interval)
elapsed_time += wait_interval
print(f"\n测试超时!任务仍在处理中,已等待{max_wait_time}秒")
print(f"任务ID: {task_id}")
print("请稍后手动查询结果")
return False
except Exception as e:
print(f"\n测试异常: {str(e)}")
return False
if __name__ == '__main__':
# 解析命令行参数
parser = argparse.ArgumentParser(description='Coze工作流测试脚本')
parser.add_argument('--source', required=True, help='源图片路径')
parser.add_argument('--target', required=True, help='目标图片路径')
parser.add_argument('--api-key', default='pat_2mYHUdcRixq90o4Nd2Jp0nPhpBcIZg4wFZkkmvxe3UHcztZdXi0glSX1rPqxHK9T',
help='Coze API密钥')
parser.add_argument('--workflow-id', default='7536960050292998154',
help='Coze工作流ID')
args = parser.parse_args()
print("=== Coze工作流测试脚本 ===")
print(f"源图片: {args.source}")
print(f"目标图片: {args.target}")
print(f"工作流ID: {args.workflow_id}")
print("\n开始测试...")
# 创建测试器并运行测试
tester = CozeWorkflowTester(
api_key=args.api_key,
workflow_id=args.workflow_id
)
tester.test_workflow(args.source, args.target)
4 同学问题
# 问题:
1 关于Trae 写的代码不是你想要的问题?
-是你的提示词写的不合适,trae没理解
-举例:现在有个特别牛逼 教授---》你是一个小学生
-你说的话---》教授没理解
-我们的基础水平没达到---》导致提示词写的不好---》没按照需求生成
-尽量多次跟Trae磨合,我们继续提升我们技术栈
2 老师 我看manage.py里并没有几行代码啊 为什么执行 python manage.py migrate 就能创建数据库表呢?
-django框架的功能--》输入命令,就会给我们干事,跟代码行数没关系
3 在服务器怎么部署
-下次课要讲
4 我们装Androidstudio干嘛?咱们不是用Trae写代码吗?
-写安卓项目:
-需要有个编辑器:Androidstudio/Trae
-需要有安卓的开发环境:需要使用Androidstudio下载和配置
-Trae做不到下载配置开发开发环境,只能写代码
-测试,运行,编译app--->上架应用市场签名--》Androidstudio才能做--》trae做不到
5 这个手机投屏图怎么弄上来啊?
-你们不讲课,不需要用这个东西
-方式一:看我视频:我操作,借助于Androidstudio投屏
-方式二:自行搜索一个软件:scrcpy
6 没有安卓手机能做吗?
-方式一:使用Androidstudio自带虚拟机测试
-看我操作
-方式二:使用第三方虚拟机--自行搜索
-网易mumu
-夜神模拟器
-雷电模拟器
7 刚才老师你说是复制链接进来 还是复制整个前端项目过来?
-整个项目,从文件夹层复制过来的
8 如果不先创建一个空的Android项目 用trae新生成一个的话 它生成的项目目录结构会不符合Android项目结构吗?
-成功率很低
-没有安卓的环境---》必须在Androidstudio中完成
9 老师,练习的时候mysql安装到虚拟机上了,还需要本地安装么
-不需要了,注意数据库连接地址
10 怎么掌握给trae发问和提要求的度,它才会比较顺利的按照你的要求完成工作?
-很多方面
1 技术积累:最重要
2 提示词写的是否完整
3 可以借助于deepseek帮我们生成提示词:辅助
4 比较trae刚出现才半年---》给她点时间
-cursor才三年
-ai编辑器处于初级阶段,还有很长的路要走
-ai 也是有很长的路要走
-问答
-生图
-生视频。。。
-情感陪伴机器人:问答
11 我们现在用http访问,如何设置https
-后续:阿里云证书 可能不讲
- 二期:微信小程序上线部分
12 mac 电脑 不好连 安卓手机
-绝对没问题
-你可能没有配置好
13 显示test endpoint,是测试通过了吗?
-我们生成的项目不需要写测试脚本
-不需要运行测试脚本
14 老师,我的后端文件在生成的时候没有创建超级用户,我用提示词创建管理员账号,终端指令内密码那块儿卡住了,不知道怎么解决
-如果生成时,没执行那个命令:python manage.py creatrsuperuser
-方式一:再提示词:帮我创建一个后台管理的超级用户
-方式二:自己在命令行中:注意路径
python manage.py creatrsuperuser #输入用户名,邮箱,密码两次,确认
-ctrl +c 关掉,重新运行
-重启机器
15 老师用的是国际版TRAE吗?
-我们用的国内版
16 数据表是哪里迁移过来的?
-从项目中生成的代码---》同步到数据库中
-自己在命令行中执行:注意路径
-python manage.py makemigrations
-python manage.py migrate
-使用提示词
- 帮我迁移后端数据库
17 老师可以用其他架构做后端吗
-案例:
-你自己写东西,爱用啥用啥
-尽量用你熟悉的
18 老师这个能写langchain、RAG嘛?
当然可以,任意代码都可以
19 为什么不直接用trae生成app代码,而要用android呢
回答过了,Androidstudio配置开发环境,编译代码,上架签名。。。
20 想用springboot
-随便--》你跟他熟,你随便
21 数据库没有表 怎么办
-python manage.py makemigrations
-python manage.py migrate
-根据项目中生成的表结构,生成进去
-手动生成
-trae提示词生成
22 最近被推了 腾讯的 ima 那个我们会讲嘛
-后续陆续会加
23 老师,给trae的提示词,我可以让DeepSeek豆包啥的写吧?
-可以,但是你也需要明白
24 如果商用发布app,也不用https吗?
-可以使用https,也可以使用http
-配置个证书即可,证书花钱
-不同商店要求不一样,甚至不需要上商店,很多app没上商店
-ios 的app,必须上架苹果应用市场才能被下载使用
-开发完--》编译---》提交到苹果应用市场--》苹果人审核--》通过--》市场才能看到
-安卓app--》应该上架 谷歌应用市场
-国内上不了
-国内很多厂商:华为,小米,腾讯应用宝,都做了自己的应用市场
-他们要求不一样
-豌豆荚,要求低一些
25 鼠标一进入finalshell区域就特别卡咋办,除了重启有好办法吗
-你电脑问题
-不使用finalshell
-xshell,其他的ssh工具 SecureCRT
26 android,项目怎么生成和导入trae
-直接完整复制过来
27 一个项目前期人工写的,可以中途使用trae写不?如果可以,需要把别人的代码拿过来给到trae不?
-咱们的安卓不就是这个吗?
-把项目复制到trae中:写提示词
-项目我已经写了,有xxx功能,你现在帮我把xx功能写完
28 苹果手机怎么用trae,写项目?也有虚拟机测试吗?测试后,只要版本一样就同真机测试环境吗?
-ios的app如何编写--》不是我们课程内容
-1 需要 苹果的系统 mac系统
-苹果的本
-平台台式机
-2 win机器写不了
-3 只要不是苹果家的电脑,通通装不了mac系统
-网上会有很多人,会写一些教程,把苹果系统转到非苹果出的电脑
-黑苹果--》基本用不了
29 手机机型那么多,自己开发的app如何适配那么多机型,需要用所有机型的真机来测试?
-正常公司开发--》公司都会买各种型号的测试机做适配--》我我们没有,只适配自己手机
-我们目标不是做一款非常流行的app---》学习为目的
30 对于业务逻辑比较复杂的应用是否适合使用TRAE开发 ?
-你的业务需要跟他交流让它理解--》自然就能写出来
31 如果有苹果本,开发能给个方法或大致怎么开发,上线苹果商店流程
-自行研究
5 通过抓包,分析前后端为什么不联通
# 1 charles
# 2 看视频配置
# 3 配置完后---》手机发送的数据包,都能被charles看到
# 4 发现接口前后端对接数据问题
# 5 给Trae提示词
帮我检查所有前后端接口对应数据,如果有问题,帮我修复
# 6 登录改好了,登录成功闪退了
app登录成,闪退了,帮我检查原因