核心原理
要理解如何调用附加表字段,首先要明白 DedeCMS 的数据结构:

(图片来源网络,侵删)
- 主表 (
dede_archives): 存储所有文章/内容的通用信息,如 ID、标题、发布时间、点击量、所属栏目、文章内容等。 - 附加表 (
dede_addonXX): 当你创建一个内容模型(产品模型”)时,系统会自动创建一个对应的附加表,这个表用来存储该模型特有的字段,如“价格”、“品牌”、“型号”等。 - 关联: 主表中的
id字段与附加表中的aid字段是一一对应的,通过这个关联,我们可以把两个表的数据连接起来。
使用 SQL 查询(最灵活、最推荐)
这是最直接、最灵活的方法,你可以在列表页模板中直接编写 SQL 语句,通过 JOIN (连接) 查询来同时获取主表和附加表的数据。
步骤:
-
找到附加表名
- 登录 DedeCMS 后台。
- 进入【核心】 -> 【内容模型管理】。
- 找到你当前列表页面对应的模型(文章模型”、“产品模型”等),点击后面的【字段管理】。
- 在浏览器地址栏中,你会看到类似
php?dopost=addField&mid=1的参数,这个mid就是模型的ID。 - 附加表的命名规则通常是
dede_addon+ 模型ID,如果模型ID是1,那么附加表名就是dede_addon1。
-
在列表页模板中编写代码
- 打开你的列表页模板文件,通常是
/templets/default/list_栏目ID.htm。 - 找到
{dede:list}标签对。 - 在
{dede:list}标签对内部,使用{field:字段名}来调用主表字段。 - 要调用附加表字段,你需要使用
array函数配合自定义的SQL查询。
- 打开你的列表页模板文件,通常是
代码示例:
假设我们有一个“产品”模型,其模型ID为 3,所以附加表是 dede_addon3,这个附加表里有两个字段:price (价格) 和 brand (品牌)。

(图片来源网络,侵删)
我们希望在列表页同时显示标题、价格和品牌。
{dede:list pagesize='10'}
<li>
<!-- 调用主表字段,方法不变 -->
<a href="[field:arcurl/]">[field:title/]</a>
<!-- 调用附加表字段,需要通过SQL查询 -->
[field:array runphp='yes']
$aid = @me['id']; // 获取当前文章的ID,这是关联的关键
// 编写SQL查询,从附加表获取数据
// 注意:这里需要根据你的实际情况修改表名 `dede_addon3` 和字段名 `price`, `brand`
$dsql->SetQuery("SELECT price, brand FROM `dede_addon3` WHERE aid = $aid");
$dsql->Execute('t');
$row = $dsql->GetArray('t');
// 拼接要输出的字符串
@me = " | 价格: " . $row['price'] . " | 品牌: " . $row['brand'];
[/field:array]
</li>
{/dede:list}
代码解析:
[field:array runphp='yes']: 这个标签会把当前文章的所有字段(以数组形式)传递给 PHP 代码。$aid = @me['id'];: 从数组中获取文章的 ID,这是连接主表和附加表的桥梁。$dsql->SetQuery(...): 设置要执行的 SQL 语句。SELECT price, brand FROM ... WHERE aid = $aid就是从附加表中查找与当前文章 ID 匹配的记录。$dsql->Execute('t')和$dsql->GetArray('t'): 执行查询并获取结果到一个数组$row中。@me = "...": 将你想要输出的内容赋值给@me变量,DedeCMS 会自动将其显示在页面上。
修改 include/arc.listview.class.php 文件(性能更高,但有侵入性)
这种方法通过修改 DedeCMS 的核心类文件,让系统在获取列表数据时就自动把附加表字段查询出来,然后在模板中直接调用,这样做的好处是模板代码更简洁,性能也稍好,但缺点是修改了核心文件,升级 DedeCMS 时可能会被覆盖,需要重新修改。
步骤:
-
备份文件:在修改之前,务必备份
include/arc.listview.class.php文件。
(图片来源网络,侵删) -
编辑文件:打开
include/arc.listview.class.php文件。 -
找到并修改
GetSql()方法: 在这个文件中搜索GetSql()方法,你会找到一个生成列表查询 SQL 语句的函数。找到类似这样的代码段(具体行号可能因版本不同而异):
// ... 在 GetSql() 方法内部 ... $query = "SELECT arc.*,tp.typedir,tp.typename,tp.corank,tp.isdefault,tp.defaultname, tp.namerule,tp.namerule2,tp.ispart,tp.moresite,tp.siteurl,tp.sitepath FROM `dede_archives` arc LEFT JOIN `dede_arctype` tp ON arc.typeid=tp.id WHERE {$this->addSql} $ordersql LIMIT $limitstart,$row"; // ...这里的
$this->addSql是存放额外查询条件的地方。 -
添加附加表连接: 在
FROM子句中,添加LEFT JOIN来连接你的附加表,假设附加表是dede_addon1,模型ID为1。修改后的 SQL 应该类似这样:
// ... 在 GetSql() 方法内部 ... $query = "SELECT arc.*,tp.typedir,tp.typename,tp.corank,tp.isdefault,tp.defaultname, tp.namerule,tp.namerule2,tp.ispart,tp.moresite,tp.siteurl,tp.sitepath, add1.* // <-- 新增:选择附加表的所有字段 FROM `dede_archives` arc LEFT JOIN `dede_arctype` tp ON arc.typeid=tp.id LEFT JOIN `dede_addon1` add1 ON arc.id=add1.aid // <-- 新增:连接附加表 WHERE {$this->addSql} $ordersql LIMIT $limitstart,$row"; // ...注意:
add1.*:add1是我们给附加表起的别名, 表示选择该表的所有字段。LEFT JOIN dede_addon1 add1 ON arc.id=add1.aid:这是连接的核心,确保arc.id(主表ID) 等于add1.aid(附加表中的文章ID)。
-
在模板中直接调用: 修改完核心文件并保存后,你就可以在列表模板中像调用主表字段一样直接调用附加表字段了。
{dede:list pagesize='10'} <li> <a href="[field:arcurl/]">[field:title/]</a> <!-- 直接调用附加表字段,非常方便! --> 价格: [field:price/] 品牌: [field:brand/] </li> {/dede:list}
总结与对比
| 特性 | SQL查询 | 修改核心文件 |
|---|---|---|
| 灵活性 | 高,每个列表页都可以写不同的SQL,逻辑清晰。 | 低,修改后所有使用该模型的列表页都会生效。 |
| 模板代码 | 稍显复杂,需要内嵌PHP代码。 | 非常简洁,直接使用 [field:字段名]。 |
| 性能 | 稍低,每次循环都要执行一次数据库查询,效率不高。 | 高,只在获取列表数据时执行一次JOIN查询,效率更高。 |
| 维护性 | 好,不修改核心文件,升级DedeCMS无忧。 | 差,修改了核心文件,升级后可能被覆盖,需要重新修改。 |
| 推荐度 | ★★★★☆ (强烈推荐),适用于大多数场景,尤其是不同列表页需求不同时。 | ★★☆☆☆ (不推荐新手),适用于对性能有极致要求且确定不会轻易升级系统的场景。 |
给你的建议:
- 对于大多数用户和项目,请优先选择【方法一:SQL查询】,它虽然代码多一点,但安全、灵活,且符合 DedeCMS 的插件化思想。
- 只有当你在一个大型、高流量的项目中,并且经过测试发现方法一的性能瓶颈确实无法接受时,才考虑使用【方法二】,如果使用方法二,请务必做好修改记录,方便后续维护。
