ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

“Frontend is solved“?我拿AI生成的网页接了个Django后端,发现事情没那么简单

“Frontend is solved“?我拿AI生成的网页接了个Django后端,发现事情没那么简单 「AI Python 系列」第 04 栏 · Web 全栈实战作者梅雅达编程笔记首发CSDN摘要Astra 零样本直出完整网页评论区齐喊前端已死我把 AI 生成网页接了 Flask 和 Django 后端发现演示品和产品之间隔着一整个后端。三种前后端对接模式实测附 prompt 公式。文中所有代码已提取为独立文件见文末。一、先刷到个大新闻网页被直出了8 月 29 号那天刷推刷到开发者 Lentils80 曝的料OpenAI 正在扩大下一代模型 Astra内部代号 mozaik-alpha-fdm的灰度测试。首批拿到资格的人晒出的东西全是 Max effort 模式下的零样本生成——注意这个零样本意思是不给范例、不给脚手架一句话就要成品。成品长什么样3D 像素城堡等距视角能点着走的王国地图GTA2 风格的 2D 游戏完整网页3D 飞船带物理效果的 3D 自行车网页还有一个第一人称 Roguelike 游戏。全部一次直出不带返工的。灰度群里的反馈更吓人模型一口气管住了统一视觉语言、元素空间关系、页面层级、交互代码结构。以前用 AI 写页面最容易翻车的就是这几样——标题颜色和按钮不搭、元素之间留白忽大忽小、z-index 层级打架、点了按钮报错都不知道错哪。Astra 这批演示里这些毛病一次性全没了。据新智元和 TestingCatalog 的解读背后是四个硬突破一是端到端多智能体编排内部并发跑着UI 设计师 前端工程师 代码审查员各自有分工二是超长程任务能力几千行的页面能一口气连贯生成三是持久化推理Max 模式下的思考量远超 GPT-5.6 Sol四是即时自我纠错——代码先在内部虚拟渲染、拿 AST 跑通确认没问题再输出。相当于交卷前自己先模拟批改了一遍。于是有人直接喊了句Frontend is solved——前端被解决了。业界预测它 9 月 3 号前后正式发布正面对线 Anthropic 的 Fable 5.1。顺带一提就是这个 Astra8 月初还因为网络安全能力触达《准备框架》的关键阈值被 OpenAI 自己暂停过部分训练。猛是真的猛。但我盯着演示视频来回看了半天发现一个没人提的细节那些页面一个接口都没调。二、下载下来一看一个孤零零的 HTML 文件我拿自己常用的 GLM 复刻了几个类似页面零成本后面说下载下来打开看。是什么一个孤零零的 HTML 文件。CSS 和 JS 全内联在里面双击就能开确实漂亮。但你试着用用看商品列表数据写死在标签里“¥99”、已售 2.3 万件全是模型编的购物车按钮点了有动画没反应购物车角标永远是 0登录注册表单画得挺像提交按钮指向#刷新页面一切归零你刚才加的购物车、填的表单烟消云散。这就是 AI 生成网页的真相它是一个自包含的静态演示品不是一个产品。从好看的页面到能用的产品中间隔着什么我给你数数数据库——商品、订单、用户得有地方存不能写在标签里用户认证——谁登录了、谁能下单、谁能看后台得有一套权限业务逻辑——库存扣减、价格计算、优惠叠加错一个就是资损部署运维——页面得上服务器、得配域名、出问题得有日志查。最有意思的是那些假交互。购物车图标上的小红点点了永远不涨表单填完点提交弹窗提示提交成功——数据去了哪哪也没去就弹了个窗。你按 F12 打开网络面板看一眼请求列表干干净净一个请求都没发出去。它表演的是一个能用的网站而不是真的能用。打个比方。AI 生成的网页就像售楼处的样板间沙发、吊灯、落地窗哪哪都好看。但你住进去试试没水、没电、没燃气下水道都是假的。样板间的任务是让你心动不是让你生活。“Frontend is solved”我看更准确的说法是前端的执行被解决了——写 CSS、调布局、堆组件这些体力活 AI 确实干得又快又好。但架构谁定数据从哪来接口长什么样出错了谁兜底这些事一个字都没被解决。三、但对 Python 开发者这是利好说句实在话这事儿对咱们写 Python 的反而是好消息。前端出样子的活被 AI 包了这本来就不是后端工程师的强项也不该花你大量时间。而接后端这活——定数据模型、写接口、把页面和真实数据打通——正好是 Python 开发者的主场而且是 AI 短期内接不住的部分。下面我用三种模式实测全程零成本。生成页面我用的是智谱的 GLM-4.7-Flash200K 上下文永久免费写页面绰绰有余。你没有这个条件也没关系任何能写代码的 AI 都行方法完全通用。三种模式不是并列的是递进的页面越活后端介入越深。你可以对照自己的需求对号入座别一上来就搞前后端分离——能用静态页解决的就别上 API。四、模式一AI 出静态页Flask 直接托管适用场景活动页、营销落地页、产品介绍页——内容本身不需要动态上线什么样就是什么样。先让 AI 生成页面。prompt 这么写帮我写一个秋季新品促销活动落地页要求单个 HTML 文件CSS 和 JS 全部内联原生 HTML/CSS/JS不要任何框架主色调暖橙色风格年轻活泼包含首屏大图、三个卖点区块、一个立即抢购按钮按钮 href 留空写 #移动端自适应。拿到promo.html之后用 Flask 托管它。整个app.py就这么点# app.pyfromflaskimportFlask,send_from_directory appFlask(__name__)app.route(/)defpromo():# 直接把静态 HTML 发出去不经过模板渲染returnsend_from_directory(pages,promo.html)if__name____main__:app.run(debugTrue,port5000)把promo.html放进项目下的pages/目录pip install flask之后跑python app.py浏览器打开http://localhost:5000就能看到。这里有个小细节。AI 生成页面时经常自作主张引一堆 CDN 资源Bootstrap、jQuery、Tailwind有的还会引 Google Fonts。内站用着没事真上线你就知道疼了——CDN 一抽风页面裸奔字体加载失败还会堵渲染。我的习惯是在 prompt 里加一句所有资源本地化或纯内联不引用任何外部 CDN它就老实了。营销页最怕的就是开屏白屏三秒这一句能帮你躲掉。有人可能要问这种页面为什么不用模板引擎为什么不直接丢 Nginx问得好。活动页的内容是死的——文案定死、价格定死、倒计时都可以是假的。既然没有动态数据模板渲染就是脱裤子放屁render_template那一层完全多余。生产环境你甚至连 Flask 都不用把文件丢到 Nginx 或者对象存储OSS、COS就行。本地开发或者内部小活动Flask 托管十几行代码搞定够用。判断标准很简单这页的数据会不会变不会变静态托管就是最优解别过度设计。五、模式二AI 出模板片段嵌进 Django Template适用场景页面大部分是固定的但有一小块要显示真实数据——比如商品列表、订单状态、用户昵称。这种页面用 Django 模板最合适AI 出 HTML 骨架动态的地方用 Django 的模板语法留口子。关键是 prompt 怎么写你得明确告诉 AI 这是 Django 模板帮我写一个商城商品列表页Django Template 语法。要求顶部导航和 banner 用静态 HTML 写死商品列表区域用 {% for good in goods_list %} 循环渲染字段写法商品名 {{ good.name }}、价格 {{ good.price }}、封面 {{ good.cover.url }}列表为空时用 {% empty %} 显示暂无商品严禁编造任何商品数据不要写死任何商品名和价格原生 CSS所有自定义 class 加 mall- 前缀避免样式冲突。注意第 4 条和第 5 条这是踩过坑才知道要写的。后端视图非常简单views.py里从 ORM 查数据传进去# views.pyfromdjango.shortcutsimportrenderfrom.modelsimportGoodsdefgoods_list(request):# 从数据库查真实商品按创建时间倒序goods_listGoods.objects.all().order_by(-created_at)returnrender(request,mall/goods_list.html,{goods_list:goods_list})模板里 AI 生成的循环长这样divclassmall-grid{% for good in goods_list %}divclassmall-cardimgsrc{{ good.cover.url }}alt{{ good.name }}h3classmall-name{{ good.name }}/h3pclassmall-price¥{{ good.price }}/p/div{% empty %}pclassmall-empty暂无商品/p{% endfor %}/div数据从数据库到页面这条路就通了。说两个必踩的坑。坑一AI 默认会编假数据。你不写严禁编造它一定在循环外面给你塞三个写死的示例商品还做得花里胡哨看不出来。上线前对着模板搜一下中文商品名和写死的价格数字能抓出一大批。坑二class 名冲突。AI 起 class 名最爱用.btn、.card、.container这种大众名。你项目里要是已有全局样式分分钟被污染——按钮颜色莫名其妙变了能查一下午。解法就是 prompt 里约定前缀比如上面的mall-让它所有自定义 class 都带上成本为零根治。还有个小经验AI 生成的模板里图片路径经常写成它瞎编的./images/p1.jpg。你本地一跑全是裂图别慌这不是 bug是它本来就没有图。把src换成真实字段或者让它在 prompt 阶段就用{{ good.cover.url }}这种写法。另外记得让它顺手加上alt属性真裂图的时候至少还能看见商品名。六、模式三前后端分离AI 出页面 DRF 出 API适用场景交互重的页面——购物车、后台管理、实时数据看板。点一下要数据、加一个要反馈纯模板扛不住。这种模式的核心思想一句话先定接口契约再让 AI 照着契约写页面。契约就是前后端之间的合同你是甲方AI 是施工队。合同长这样。统一响应格式{code:0,message:success,data:{}}接口列表GET /api/goods/获取商品列表data 是数组每项含 id、name、price、coverPOST /api/order/提交订单请求体含 goods_id 和 quantity成功返回订单号后端用 DRF 实现。序列化器# serializers.pyfromrest_frameworkimportserializersfrom.modelsimportGoodsclassGoodsSerializer(serializers.ModelSerializer):classMeta:modelGoods fields[id,name,price,cover]视图# views.pyfromrest_framework.decoratorsimportapi_viewfromrest_framework.responseimportResponsefrom.modelsimportGoods,Orderfrom.serializersimportGoodsSerializerapi_view([GET])defgoods_api(request):goodsGoods.objects.all()dataGoodsSerializer(goods,manyTrue).data# 统一包装成约定好的响应格式returnResponse({code:0,message:success,data:data})api_view([POST])deforder_api(request):goods_idrequest.data.get(goods_id)quantityrequest.data.get(quantity,1)# 真实业务里这里要查库存、算价格、包事务orderOrder.objects.create(goods_idgoods_id,quantityquantity)returnResponse({code:0,message:success,data:{order_no:order.order_no}})然后把契约原样甩给 AI让它写纯静态页面加 fetch 调用。它生成的 JS 大概长这样asyncfunctionloadGoods(){constresawaitfetch(/api/goods/);constjsonawaitres.json();// 按契约判断成功与否if(json.code!0){alert(加载失败json.message);return;}constlistdocument.querySelector(#goods-list);// 用字符串拼接渲染卡片字段全部来自接口数据list.innerHTMLjson.data.map(function(item){return(div classcardimg srcitem.cover altitem.nameh3item.name/h3p¥item.price/pbutton onclickbuy(item.id)立即下单/button/div);}).join();}asyncfunctionbuy(goodsId){constresawaitfetch(/api/order/,{method:POST,headers:{Content-Type:application/json},body:JSON.stringify({goods_id:goodsId,quantity:1}),});constjsonawaitres.json();if(json.code0){alert(下单成功订单号json.data.order_no);}else{alert(下单失败json.message);}}loadGoods();跑起来看看页面是 AI 画的数据是数据库里的点按钮真的会生成订单。样板间通水电了。这一步有个真实的坑我替你踩过了POST 接口刚接上那会儿下单一直报 403。查了半天才反应过来——Django 默认开启 CSRF 保护而 AI 生成的静态页面根本不知道什么叫 CSRF token。两条路正规做法是用 DRF 的 TokenAuthentication 或 SessionAuthentication前端登录后带着令牌请求图快的内部项目给这个视图加csrf_exempt先跑通也行但你要清楚这意味着放开了一道防护公网项目千万别这么干。你看这种框架的脾气AI 不看你的项目配置是不可能知道的得靠你自己的工程经验兜底。另外校验逻辑要放在序列化器里别信前端传上来的任何东西。quantity传个 -100 或者 999999你在后端不拦着数据库就敢给你存。AI 写的前端只会做看起来对的校验真正的防线永远在后端。这一步最值钱的是什么是契约。code等于几算成功、字段叫goods_id还是goodsId、错误信息放哪个字段——全是你定的AI 只是照着填。它不知道你的业务也不需要知道。定规则比写代码值钱这就是最直白的例子。七、让 AI 生成能接后端页面的 prompt 怎么写三种模式讲完规律其实就一条别让 AI 自由发挥把约束给足。我自己用的是四段式套着写就行。先说清技术栈。这是纯静态 HTML、是 Django 模板、还是前后端分离用 fetch 调接口一句话定性AI 的输出格式立刻不一样。再约定数据占位。动态数据一律用占位符或模板变量明令禁止编造数据。写页面时给假数据当示例可以但必须注明示例数据实现时替换。然后约定接口。列出接口路径、请求方法、请求体、响应格式最好贴一段真实的响应 JSON 示例。AI 照着示例写字段名都不会错。最后约定风格。主色调、组件库不用框架就明说原生 CSS、class 命名前缀一次说清省得回来返工。这四条看着啰嗦其实是在替你省时间。AI 写页面的速度太快了快到你返工的成本远高于把话说清楚的成本。一次需求喂不饱来回拉扯三轮你一下午就没了把约束写全一轮出活这才是用 AI 的正确姿势。我自己的习惯是把这套模板存成一个文本文件换项目只改括号里的内容。组合起来一个可以直接抄的 prompt 模板帮我写一个【页面名称】【纯静态 HTML / Django Template / 前后端分离静态页加 fetch】。技术要求原生 CSS/JS不使用框架主色调【颜色】自定义 class 统一加【前缀】前缀。数据要求动态数据一律用【占位符 / {{ 变量 }} / fetch 调用】严禁编造任何业务数据。接口约定GET /api/xxx/ 返回【贴一段真实响应 JSON】POST /api/yyy/ 请求体为【字段说明】。页面包含【区块清单】。八、写在最后绕回 Astra。9 月 3 号它大概率就发布了到时候一句话生成网页的演示会铺天盖地评论区还会接着喊前端失业。我信它能把页面做得越来越炫——多智能体编排、持久化推理、输出前自我纠错这些技术我都信。但模型再强缩短的也是想法到页面的距离。页面到产品的距离它一寸都没缩短。那一段路叫工程是 Python 里的业务逻辑是数据库里的表结构是接口契约里的字段约定是出了问题能顺着日志查回源头的底气。而且你发现没有这条路 AI 越是想替你走越需要有人在前面把路标立好。它生成的代码越多审代码、定规范、兜底线的人就越稀缺。以前一个团队三个前端切图现在可能只需要一个懂架构的全栈带着 AI 就把活干了。所以我的判断是前端工程师不会消失但只会切图的会全栈开发者的价值不但没缩水反而被放大了——以前你写十行 CSS 的时间现在能多定三个接口。AI 负责把样板间盖得漂漂亮亮你负责通水通电。文中代码已提取为独立文件存放于番外_代码/目录文件对应模式说明01_flask_app.py模式一Flask 托管静态页02_django_goods_views.py模式二Django 商品列表视图03_goods_list.html模式二Django 模板片段04_response_format.json模式三统一响应格式05_drf_serializers.py模式三DRF 序列化器06_drf_api_views.py模式三DRF API 视图07_frontend_api.js模式三前端 fetch 调用
返回列表