import re import zipfile from pathlib import Path from django.conf import settings from django.test import SimpleTestCase class DocxTemplateRenderTest(SimpleTestCase): def _extract_doc_text(self, docx_path: str) -> str: with zipfile.ZipFile(docx_path, "r") as zf: xml = zf.read("word/document.xml").decode("utf-8", errors="replace") # Extract only text to avoid false positives in tags/attrs. import xml.etree.ElementTree as ET ns = {"w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main"} root = ET.fromstring(xml) texts = [(el.text or "") for el in root.findall(".//w:t", ns)] return "".join(texts) def test_render_replaces_and_clears_placeholders(self): template_path = str(Path(settings.BASE_DIR) / "print-template.docx") self.assertTrue(Path(template_path).exists()) from printing.docx_template import render_docx_template out_path = str(Path(settings.BASE_DIR) / ".tmp_docx" / "rendered-test.docx") Path(out_path).parent.mkdir(parents=True, exist_ok=True) render_docx_template( template_path=template_path, output_path=out_path, context={ # hash placeholder inner key "打印-销售单(8*9).客户名称": "客户A", # plain brace placeholder inner key "备注": "这是备注", }, clear_unresolved=True, ) text = self._extract_doc_text(out_path) self.assertIn("客户A", text) self.assertIn("这是备注", text) # No raw placeholders should remain when clear_unresolved=True self.assertIsNone( re.search(r"#\{.{1,300}?\}", text, flags=re.S), msg="仍残留 #{...} 占位符", ) self.assertIsNone( re.search(r"(?