Python使用Free Spire.Doc for Python操作Word书签的完整教学

 更新时间:2026年10月03日 08:08:43   作者:大丸子  
本文详细讲解了Python使用FreeSpire.Doc for Python创建书签、替换文本和表格、插入图片、提取内容以及删除书签的全过程,文中的示例代码讲解详细,有需要的小伙伴可以参考下

Word 书签是文档中一段被命名标记的区域,作用类似编程中的变量——定义一次,按名引用。在报告模板中预先插入书签,程序运行时将书签内容替换为实际数据,就能把"模板 + 数据 = 文档"的流程完全自动化。相比手动查找替换,书签定位精确、可嵌套、可复用,且不依赖文档中的唯一文本片段。

本文使用 Free Spire.Doc for Python 演示 Word 书签的完整操作链:创建书签、替换文本与表格内容、在书签位置插入图片、提取书签内容、删除书签,以及将这些操作组合为项目报告的自动生成流程。

pip install spire.doc.free

1. 创建书签:在文档中标记内容位置

书签由一对标记定义:AppendBookmarkStart("name") 和 AppendBookmarkEnd("name"),两者之间的内容即为书签覆盖范围。下面创建一个项目报告模板,在待填充位置插入 10 个书签:

from spire.doc import *
from spire.doc.common import *

document = Document()
section = document.AddSection()

# 标题
p = section.AddParagraph()
p.AppendText("Project Phase Report")
p.ApplyStyle(BuiltinStyle.Heading1)
p.Format.HorizontalAlignment = HorizontalAlignment.Center

# 基本信息区——用书签标记待填充位置
p = section.AddParagraph()
p.AppendText("Project Name: ")
p.AppendBookmarkStart("ProjectName")
p.AppendText("(to be filled)")
p.AppendBookmarkEnd("ProjectName")

p = section.AddParagraph()
p.AppendText("Client: ")
p.AppendBookmarkStart("ClientName")
p.AppendText("(to be filled)")
p.AppendBookmarkEnd("ClientName")

p = section.AddParagraph()
p.AppendText("Report Date: ")
p.AppendBookmarkStart("ReportDate")
p.AppendText("(to be filled)")
p.AppendBookmarkEnd("ReportDate")

p = section.AddParagraph()
p.AppendText("Project Phase: ")
p.AppendBookmarkStart("ProjectPhase")
p.AppendText("(to be filled)")
p.AppendBookmarkEnd("ProjectPhase")

section.AddParagraph()

# 项目摘要
p = section.AddParagraph()
p.AppendText("Project Summary")
p.ApplyStyle(BuiltinStyle.Heading2)

p = section.AddParagraph()
p.AppendBookmarkStart("Summary")
p.AppendText("(Auto-filled by program)")
p.AppendBookmarkEnd("Summary")

section.AddParagraph()

# 里程碑进度表占位
p = section.AddParagraph()
p.AppendText("Milestone Status")
p.ApplyStyle(BuiltinStyle.Heading2)

p = section.AddParagraph()
p.AppendBookmarkStart("MilestoneTable")
p.AppendText("(Auto-inserted by program)")
p.AppendBookmarkEnd("MilestoneTable")

section.AddParagraph()

# 风险与建议——嵌套书签
p = section.AddParagraph()
p.AppendText("Risk and Suggestions")
p.ApplyStyle(BuiltinStyle.Heading2)

p = section.AddParagraph()
p.AppendBookmarkStart("RiskSection")
p.AppendBookmarkStart("RiskLevel")
p.AppendText("(risk level to be filled)")
p.AppendBookmarkEnd("RiskLevel")
p.AppendText(". ")
p.AppendBookmarkStart("RiskDetail")
p.AppendText("(risk detail to be filled)")
p.AppendBookmarkEnd("RiskDetail")
p.AppendBookmarkEnd("RiskSection")

section.AddParagraph()

# 签章区
p = section.AddParagraph()
p.AppendText("Signature")
p.ApplyStyle(BuiltinStyle.Heading2)

p = section.AddParagraph()
p.AppendBookmarkStart("Signature")
p.AppendText("(Auto-inserted by program)")
p.AppendBookmarkEnd("Signature")

document.SaveToFile("template.docx", FileFormat.Docx)
document.Close()

风险与建议一节用了嵌套书签:外层 RiskSection 包裹 RiskLevel 和 RiskDetail 两个内层书签,三者同处一个段落。嵌套书签的好处是可以单独替换内层内容,也可以整体操作外层内容。AppendBookmarkStart 和 AppendBookmarkEnd 必须成对出现,名称一致,且 End 必须在 Start 之后。

运行后模板包含 10 个书签:

Template created: template.docx
Bookmark count: 10
Bookmarks: ['ProjectName', 'ClientName', 'ReportDate', 'ProjectPhase',
            'Summary', 'MilestoneTable', 'RiskSection', 'RiskLevel',
            'RiskDetail', 'Signature']

报告模板效果

2. 替换书签内容:文本与表格

替换文本内容

BookmarksNavigator 是书签操作的核心类。通过 MoveToBookmark 定位到指定书签后,ReplaceBookmarkContent 将书签覆盖的内容替换为新文本:

from spire.doc import *
from spire.doc.common import *

doc = Document()
doc.LoadFromFile("template.docx")

navigator = BookmarksNavigator(doc)

navigator.MoveToBookmark("ProjectName")
navigator.ReplaceBookmarkContent("Smart City Data Platform Phase II", False)

navigator.MoveToBookmark("ClientName")
navigator.ReplaceBookmarkContent("Orient Municipal Group", False)

navigator.MoveToBookmark("ReportDate")
navigator.ReplaceBookmarkContent("September 28, 2026", False)

navigator.MoveToBookmark("ProjectPhase")
navigator.ReplaceBookmarkContent("Phase II - Mid-term Acceptance", False)

navigator.MoveToBookmark("Summary")
navigator.ReplaceBookmarkContent(
    "This phase completed a comprehensive upgrade of the data collection module, "
    "adding 320 sensor access points and increasing daily data throughput from "
    "120 million to 350 million records. The platform has integrated with 5 subsystems "
    "(traffic, environmental, security, water, and municipal), with an average API "
    "response time of 87ms and 99.6% availability. Mid-term acceptance passed 13 of "
    "14 indicators; the remaining 1 (real-time alert latency) is expected to meet "
    "the target by October 15.", False)

# 嵌套书签的内层可以单独替换
navigator.MoveToBookmark("RiskLevel")
navigator.ReplaceBookmarkContent("Medium", False)

navigator.MoveToBookmark("RiskDetail")
navigator.ReplaceBookmarkContent(
    "The Kafka cluster on which the real-time alert module depends experienced "
    "message accumulation during peak hours, with a peak latency of 4.2 seconds, "
    "exceeding the 2-second SLA limit. The ops team has been coordinated to expand "
    "to 6 nodes, expected to complete by October 10.", False)

doc.SaveToFile("step2_text.docx", FileFormat.Docx)
doc.Close()

ReplaceBookmarkContent 的第二个参数是布尔值,控制是否保留书签原有的字符格式。传 False 时新文本使用默认格式,传 True 时继承书签内原有文本的字体、字号、颜色等属性。模板中书签内容是 "(to be filled)" 占位文本,如果模板设计者把这些占位文本设为特定格式(比如蓝色宋体),传 True 可以让替换后的数据保持同样的外观。

嵌套书签的内层 RiskLevel 和 RiskDetail 可以独立定位和替换,与外层 RiskSection 互不干扰。MoveToBookmark 按名称查找,不关心书签的嵌套层级。

替换为表格

书签内容不限于文本,也可以替换为表格。先构建 Table 对象,再通过 TextBodyPart 包装后替换:

doc = Document()
doc.LoadFromFile("step2_text.docx")

table = Table(doc, True)
table.ResetCells(6, 4)
data = [
    ["Milestone", "Planned Date", "Actual Date", "Status"],
    ["Requirements", "2026-07-15", "2026-07-14", "Completed"],
    ["Architecture", "2026-07-30", "2026-07-30", "Completed"],
    ["Core Development", "2026-08-31", "2026-09-02", "Completed (2-day delay)"],
    ["Integration Test", "2026-09-20", "—", "In Progress (85%)"],
    ["Mid-term Review", "2026-09-28", "2026-09-28", "Passed"],
]

for i in range(6):
    for j in range(4):
        cell = table.Rows[i].Cells[j]
        para = cell.AddParagraph()
        txtRange = para.AppendText(data[i][j])
        if i == 0:
            txtRange.CharacterFormat.Bold = True

navigator = BookmarksNavigator(doc)
navigator.MoveToBookmark("MilestoneTable")

part = TextBodyPart(doc)
part.BodyItems.Add(table)
navigator.ReplaceBookmarkContent(part)

doc.SaveToFile("step3_table.docx", FileFormat.Docx)
doc.Close()

Table(doc, True) 的第二个参数 True 启用表格的固定布局模式,列宽由 ResetCells 自动分配。TextBodyPart 是承载表格的容器——ReplaceBookmarkContent 接受字符串和 TextBodyPart 两种参数类型,后者用于替换结构化内容(表格、多段落等)。

填充后的报告

3. 在书签位置插入图片

向书签位置插入图片需要借助 InsertParagraph 方法。由于 AppendPicture 必须在段落上调用,而书签位置不一定有现成的空段落,操作方式是先在一个临时 section 中创建带图片的段落,再将该段落插入到书签位置:

doc = Document()
doc.LoadFromFile("step3_table.docx")

bn = BookmarksNavigator(doc)
bn.MoveToBookmark("Signature", True, True)

# 创建临时 section 放图片段落
section0 = doc.AddSection()
paragraph = section0.AddParagraph()
paragraph.Format.HorizontalAlignment = HorizontalAlignment.Center

picture = paragraph.AppendPicture("signature.png")
picture.Width = 150.0
picture.Height = 150.0

# 将图片段落插入书签位置
bn.InsertParagraph(paragraph)

# 移除临时 section
doc.Sections.Remove(section0)

doc.SaveToFile("step4_image.docx", FileFormat.Docx)
doc.Close()

MoveToBookmark("Signature", True, True) 的后两个参数控制查找行为:第一个 True 表示是否区分大小写,第二个 True 表示是否向前搜索。InsertParagraph 将段落插入到书签当前位置之后,图片随之落入文档。临时 section 在插入完成后移除,不产生多余页面。

picture.Width 和 picture.Height 的单位是磅(point),150 磅约等于 5.3 厘米,适合圆形签章的尺寸。如果插入的是横幅图片,可以按比例设置,比如 Width = 400.0, Height = 100.0。

签章插入效果

4. 提取与列举书签内容

处理他人提供的文档时,经常需要先了解文档中有哪些书签、各书签包含什么内容。

列举所有书签

document.Bookmarks 是书签集合,支持按索引和按名称两种方式访问:

doc = Document()
doc.LoadFromFile("step4_image.docx")

for i in range(doc.Bookmarks.Count):
    bm = doc.Bookmarks[i]
    print(f"  {i+1}. {bm.Name}")

print(f"Total: {doc.Bookmarks.Count} bookmarks")

# 按名称直接访问
bookmark = doc.Bookmarks["ProjectName"]
print(f"ProjectName bookmark found, name: {bookmark.Name}")

输出:

  1. ProjectName
  2. ClientName
  3. ReportDate
  4. ProjectPhase
  5. Summary
  6. MilestoneTable
  7. RiskSection
  8. RiskLevel
  9. RiskDetail
  10. Signature
Total: 10 bookmarks

提取书签文本

BookmarksNavigator.GetBookmarkContent() 返回书签覆盖的内容对象,遍历其 BodyItems 可以取出文本:

navigator = BookmarksNavigator(doc)

targets = ["ProjectName", "ClientName", "Summary", "RiskLevel", "RiskDetail"]
for name in targets:
    navigator.MoveToBookmark(name)
    content = navigator.GetBookmarkContent()
    text = ""
    for i in range(content.BodyItems.Count):
        item = content.BodyItems.get_Item(i)
        if isinstance(item, Paragraph):
            for j in range(item.ChildObjects.Count):
                child = item.ChildObjects.get_Item(j)
                if isinstance(child, TextRange):
                    text += child.Text
    display = text[:80] + "..." if len(text) > 80 else text
    print(f"  [{name}] {display}")

输出:

  [ProjectName] Smart City Data Platform Phase II
  [ClientName] Orient Municipal Group
  [Summary] This phase completed a comprehensive upgrade of the data collection module, addi...
  [RiskLevel] Medium
  [RiskDetail] The Kafka cluster on which the real-time alert module depends experienced messag...

GetBookmarkContent 返回的 TextBodyPart 中可能包含段落、表格等多种元素,遍历时需要用 isinstance 判断类型。对于纯文本书签,只处理 Paragraph 和 TextRange 即可;如果书签覆盖了表格,还需要处理 Table 类型。

5. 删除书签与书签内容

删除操作有两种:只删书签标记(保留内容)和同时删除标记与内容。

删除书签标记,保留内容

document.Bookmarks.Remove(bookmark) 只移除书签的 Start 和 End 标记,书签内的文本或表格原样保留在文档中:

doc = Document()
doc.LoadFromFile("step4_image.docx")

bookmark = doc.Bookmarks["RiskSection"]
doc.Bookmarks.Remove(bookmark)

doc.SaveToFile("step6a_remove_mark.docx", FileFormat.Docx)
doc.Close()
# 删除后剩余 9 个书签(原 10 个减去 RiskSection)

这种操作适用于报告定稿阶段:填充完成后移除所有书签标记,输出干净的最终文档,同时保留填充的内容。

删除书签及其内容

要同时删除书签标记和内容,需要手动定位 BookmarkStart 和 BookmarkEnd 在段落中的位置索引,然后逐个移除两者之间的子对象:

doc = Document()
doc.LoadFromFile("step4_image.docx")

bookmark = doc.Bookmarks["Signature"]
para = bookmark.BookmarkStart.Owner
startIndex = para.ChildObjects.IndexOf(bookmark.BookmarkStart)
para2 = bookmark.BookmarkEnd.Owner
endIndex = para2.ChildObjects.IndexOf(bookmark.BookmarkEnd)

# 移除 Start 和 End 之间的内容
for i in range(startIndex + 1, endIndex):
    para.ChildObjects.RemoveAt(startIndex + 1)

# 再移除书签标记本身
doc.Bookmarks.Remove(bookmark)

doc.SaveToFile("step6b_remove_content.docx", FileFormat.Docx)
doc.Close()
# 删除后剩余 9 个书签

BookmarkStart.Owner 返回书签标记所在的段落对象,ChildObjects.IndexOf 获取标记在段落子对象列表中的位置。循环 RemoveAt(startIndex + 1) 每次删除 Start 后面的第一个元素,直到删到 End 前一个位置为止。注意 RemoveAt 后列表会移位,所以循环中始终删除 startIndex + 1 位置而非递增索引。

6. 综合应用:项目报告自动生成

将上述操作组合起来,一个完整的报告生成流程是:创建带书签的模板 → 替换文本书签 → 替换表格书签 → 插入签章图片 → 保存输出。以下脚本一次运行完成全部步骤:

from spire.doc import *
from spire.doc.common import *
document = Document()
section = document.AddSection()
# --- 创建模板 ---
p = section.AddParagraph()
p.AppendText("Project Phase Report")
p.ApplyStyle(BuiltinStyle.Heading1)
p.Format.HorizontalAlignment = HorizontalAlignment.Center
fields = [
    ("Project Name: ", "ProjectName"),
    ("Client: ", "ClientName"),
    ("Report Date: ", "ReportDate"),
    ("Project Phase: ", "ProjectPhase"),
]
for label, bm in fields:
    p = section.AddParagraph()
    p.AppendText(label)
    p.AppendBookmarkStart(bm)
    p.AppendText("(to be filled)")
    p.AppendBookmarkEnd(bm)
section.AddParagraph()
p = section.AddParagraph()
p.AppendText("Project Summary")
p.ApplyStyle(BuiltinStyle.Heading2)
p = section.AddParagraph()
p.AppendBookmarkStart("Summary")
p.AppendText("(to be filled)")
p.AppendBookmarkEnd("Summary")
section.AddParagraph()
p = section.AddParagraph()
p.AppendText("Milestone Status")
p.ApplyStyle(BuiltinStyle.Heading2)
p = section.AddParagraph()
p.AppendBookmarkStart("MilestoneTable")
p.AppendText("(to be filled)")
p.AppendBookmarkEnd("MilestoneTable")
section.AddParagraph()
p = section.AddParagraph()
p.AppendText("Risk and Suggestions")
p.ApplyStyle(BuiltinStyle.Heading2)
p = section.AddParagraph()
p.AppendBookmarkStart("RiskLevel")
p.AppendText("(to be filled)")
p.AppendBookmarkEnd("RiskLevel")
p.AppendText(". ")
p.AppendBookmarkStart("RiskDetail")
p.AppendText("(to be filled)")
p.AppendBookmarkEnd("RiskDetail")
section.AddParagraph()
p = section.AddParagraph()
p.AppendText("Signature")
p.ApplyStyle(BuiltinStyle.Heading2)
p = section.AddParagraph()
p.AppendBookmarkStart("Signature")
p.AppendText("(to be filled)")
p.AppendBookmarkEnd("Signature")
# --- 填充文本 ---
navigator = BookmarksNavigator(document)
text_data = {
    "ProjectName": "Smart City Data Platform Phase II",
    "ClientName": "Orient Municipal Group",
    "ReportDate": "September 28, 2026",
    "ProjectPhase": "Phase II - Mid-term Acceptance",
    "Summary": "This phase completed a comprehensive upgrade of the data collection module, "
               "adding 320 sensor access points and increasing daily data throughput from "
               "120 million to 350 million records. The platform has integrated with 5 subsystems "
               "(traffic, environmental, security, water, and municipal), with an average API "
               "response time of 87ms and 99.6% availability. Mid-term acceptance passed 13 of "
               "14 indicators; the remaining 1 (real-time alert latency) is expected to meet "
               "the target by October 15.",
    "RiskLevel": "Medium",
    "RiskDetail": "The Kafka cluster on which the real-time alert module depends experienced "
                  "message accumulation during peak hours, with a peak latency of 4.2 seconds, "
                  "exceeding the 2-second SLA limit. The ops team has been coordinated to expand "
                  "to 6 nodes, expected to complete by October 10.",
}
for name, value in text_data.items():
    navigator.MoveToBookmark(name)
    navigator.ReplaceBookmarkContent(value, False)
# --- 插入里程碑表格 ---
table = Table(document, True)
table.ResetCells(6, 4)
data = [
    ["Milestone", "Planned Date", "Actual Date", "Status"],
    ["Requirements", "2026-07-15", "2026-07-14", "Completed"],
    ["Architecture", "2026-07-30", "2026-07-30", "Completed"],
    ["Core Development", "2026-08-31", "2026-09-02", "Completed (2-day delay)"],
    ["Integration Test", "2026-09-20", "—", "In Progress (85%)"],
    ["Mid-term Review", "2026-09-28", "2026-09-28", "Passed"],
]
for i in range(6):
    for j in range(4):
        cell = table.Rows[i].Cells[j]
        para = cell.AddParagraph()
        txtRange = para.AppendText(data[i][j])
        if i == 0:
            txtRange.CharacterFormat.Bold = True
navigator.MoveToBookmark("MilestoneTable")
part = TextBodyPart(document)
part.BodyItems.Add(table)
navigator.ReplaceBookmarkContent(part)
# --- 插入签章图片 ---
bn = BookmarksNavigator(document)
bn.MoveToBookmark("Signature", True, True)
section0 = document.AddSection()
paragraph = section0.AddParagraph()
paragraph.Format.HorizontalAlignment = HorizontalAlignment.Center
picture = paragraph.AppendPicture("signature.png")
picture.Width = 150.0
picture.Height = 150.0
bn.InsertParagraph(paragraph)
document.Sections.Remove(section0)
# --- 保存 ---
document.SaveToFile("final_report.docx", FileFormat.Docx)
document.Close()

运行结果:

Final report generated: final_report.docx
Bookmark count: 9
Bookmarks: ['ProjectName', 'ClientName', 'ReportDate', 'ProjectPhase',
            'Summary', 'MilestoneTable', 'RiskLevel', 'RiskDetail', 'Signature']

最终报告包含 9 个书签(综合模板未创建外层 RiskSection,只保留了内层的 RiskLevel 和 RiskDetail)。书签在替换后仍然存在于文档中,可以用于后续的二次填充或内容提取。如果需要输出不含书签的定稿,在保存前遍历 document.Bookmarks 逐个 Remove 即可。

最终报告效果

7. 关键类与方法

类 / 方法说明
Paragraph.AppendBookmarkStart(name)在段落中添加书签起始标记
Paragraph.AppendBookmarkEnd(name)在段落中添加书签结束标记
Document.Bookmarks书签集合,支持按索引 [0] 和按名称 ["name"] 访问
Document.Bookmarks.Remove(bookmark)删除书签标记,保留内容
BookmarksNavigator(doc)书签导航器,用于定位和操作书签内容
BookmarksNavigator.MoveToBookmark(name)定位到指定书签
BookmarksNavigator.GetBookmarkContent()获取书签覆盖的内容对象
BookmarksNavigator.ReplaceBookmarkContent(text, isKeepFormat)替换书签内容为文本
BookmarksNavigator.ReplaceBookmarkContent(textBodyPart)替换书签内容为结构化内容(表格等)
BookmarksNavigator.InsertParagraph(paragraph)在书签位置插入段落
TextBodyPart(doc)内容容器,用于包装表格等结构化内容

8. 适用场景

书签方案适合"模板固定、数据变化"的文档生成任务。模板由业务人员设计并插入书签,程序负责填充——两者解耦,修改模板格式不影响填充逻辑。

典型场景包括:项目报告定期生成(周报、月报、阶段验收报告)、合同模板填充(甲乙方信息、金额、期限)、产品说明书组装(按配置选取章节插入主文档)、批量通知函生成(收件人、事项、金额各异)。当填充来源是数据库或 Excel 时,将查询结果组织为字典,循环调用 ReplaceBookmarkContent 即可批量产出。

与邮件合并相比,书签方案的优势在于可以插入表格、图片等结构化内容,且不要求模板中预先存在合并域。劣势是批量生成时每次需要重新加载模板文件(ReplaceBookmarkContent 会消耗书签),而邮件合并的 Execute 方法可以一次性填充多个域。两者可以根据具体需求选用。

以上就是Python使用Free Spire.Doc for Python操作Word书签的完整教学的详细内容,更多关于Python操作Word书签的资料请关注脚本之家其它相关文章!

相关文章

  • python读取当前目录下的CSV文件数据

    python读取当前目录下的CSV文件数据

    这篇文章主要为大家详细介绍了python读取当前目录下的CSV文件数据,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03
  • Python列表(list)常用操作方法小结

    Python列表(list)常用操作方法小结

    这篇文章主要介绍了Python列表(list)常用操作方法小结,本文讲解了常用操作方法和一些简单代码实例,需要的朋友可以参考下
    2015-02-02
  • Python定时器实例代码

    Python定时器实例代码

    这篇文章主要介绍了Python定时器实例代码,向大家分享了两部分代码示例,一个是通过线程实现定时器timer,另一个是Python实现的精度可调的定时器实例,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11
  • python 快速排序代码

    python 快速排序代码

    闲来无事写了个python快排序
    2009-11-11
  • django创建css文件夹的具体方法

    django创建css文件夹的具体方法

    在本文里小编给大家总结的是关于django创建css文件夹的具体方法,对此有需要的朋友们参考下吧。
    2020-07-07
  • pyqt5自定义信号实例解析

    pyqt5自定义信号实例解析

    这篇文章主要介绍了pyqt5自定义信号实例解析,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
    2018-01-01
  • Python softmax实现及数值稳定性详解

    Python softmax实现及数值稳定性详解

    这篇文章主要为大家介绍了Python softmax实现及数值稳定性详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • Python PDF解析入门之提取信息,表格与元数据

    Python PDF解析入门之提取信息,表格与元数据

    PDF是日常工作中最常用的文档格式之一,本文将介绍如何使用 Free Spire.PDF for Python 这个免费库来完成常见的 PDF 读取任务,更希望的小伙伴可以了解下
    2026-06-06
  • 解决pytorch GPU 计算过程中出现内存耗尽的问题

    解决pytorch GPU 计算过程中出现内存耗尽的问题

    今天小编就为大家分享一篇解决pytorch GPU 计算过程中出现内存耗尽的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-08-08
  • 详解Django自定义图片和文件上传路径(upload_to)的2种方式

    详解Django自定义图片和文件上传路径(upload_to)的2种方式

    这篇文章主要介绍了详解Django自定义图片和文件上传路径(upload_to)的2种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12

最新评论