
Tandoor Recipes 全功能解析开源菜谱管理、膳食规划与数据导入导出实战指南【免费下载链接】recipesApplication for managing recipes, planning meals, building shopping lists and much much more!项目地址: https://gitcode.com/GitHub_Trending/re/recipes导读本文以仓库主页文档 docs/index.md 为骨架系统梳理 Tandoor Recipes 这一开源菜谱管理系统的完整能力从菜谱管理、膳食计划、购物清单等核心功能到全文搜索、标签系统、批量导入等进阶特性并深入展开其引用的导入导出体系对应 docs/features/import_export.md。读者读完将掌握 Tandoor 的部署形态、功能边界、数据迁移到 Tandoor 的完整操作流程以及导入导出模块的源码级实现原理。Tandoor Recipes 项目主页展示的应用界面预览覆盖菜谱浏览、搜索与组织等核心场景。一、Tandoor Recipes 是什么项目定位与核心目标Tandoor Recipes 是一款管理不断增长的数字化菜谱收藏的开源应用其定位明确面向拥有大量菜谱、希望与家人朋友分享或有序收藏的个人用户与家庭。项目主页同时强调了一个重要边界——应用带有基础权限系统但不打算作为公开网站对外运行见 docs/index.md。从仓库结构可以确认其技术栈为典型的现代 Web 应用后端Django Django REST Framework入口配置见 recipes/settings.py、recipes/urls.py核心业务模型集中在 cookbook/models.py前端Vue 3 单页应用源码位于 vue3/src配合 Vuetify 组件库vue3/src/vuetify.ts部署形态官方推荐 Docker 容器化部署仓库同时提供 Kubernetes、Unraid、Synology 等平台的示例与文档见 docs/install 目录下的 docker.md、kubernetes.md、unraid.md、synology.md。项目主页将其定位概括为由高级用户打造、为高级用户服务Made by and for power users下文将逐项展开其核心能力。二、核心功能从菜谱到餐桌的一站式闭环2.1 菜谱管理Manage your recipesTandoor 的核心是快速、直观的菜谱编辑器。从数据模型cookbook/models.py看每条 Recipe 承载了完整的结构化信息名称、描述、准备/等待时间、份数与份数文本、营养信息按份或按菜谱计量、步骤Step、食材Ingredient以及关键词标签Keyword等足以支撑从菜谱录入到精细检索的全链路。2.2 膳食计划Plan multiple meals for each day应用支持每天规划多餐MealPlan 数据模型将日期、膳食类型MealType如早餐/午餐/晚餐与菜谱关联为后续生成购物清单提供直接输入。2.3 购物清单Shopping lists购物清单存在两种生成路径经由膳食计划自动汇总或直接从菜谱添加。这一设计让计划吃什么与去超市买什么形成闭环。仓库中还扩展了超市Supermarket分组、食材忽略ignore_shopping等精细控制相关模型与迁移可见 cookbook/models.py 与 cookbook/migrations 中 0075 之后的多次演进。2.4 食谱书Cookbooks食谱书将散落的菜谱收集成书RecipeBook 与 RecipeBookEntry 模型支持按顺序组织条目cookbook/migrations/0239_add_ordering_property_recipebookentry.py方便建立自己的主题合集。2.5 分享与协作Share and collaborate项目支持与家人朋友共享菜谱并协作用户User、空间Space、邀请链接InviteLink等模型共同构成了多用户隔离与权限基础同时开发者明确提示项目带基础权限系统但不适合作为公共站点运行。2.6 更多实用特性All the must haves主页还罗列了一组高频需求特性移动端优化前端为移动设备做了适配随时随地记录与查询多语言本地化仓库 recipes/locale 与 cookbook/locale 下收录了 30 语言的翻译文件.po/.mo并由社区持续维护菜谱缩放按份数自动换算食材用量图片压缩图片处理集中在 cookbook/helper/image_processing.py导入时自动处理打印视图为纸质归档优化的打印页面超市管理购物清单可按超市维度整理。三、面向高级用户的深度能力Made by and for power users3.1 强大且可定制的全文搜索TrigramSimilarityTandoor 的搜索基于 PostgreSQL 全文检索并叠加TrigramSimilarity三元组相似度支持模糊匹配——即使拼写有偏差也能召回结果。搜索相关实现位于 cookbook/helper/recipe_search.py配套的测试覆盖见 cookbook/tests/other/test_recipe_search_* 系列。3.2 标签系统与批量操作用户可以创建、搜索标签并按过滤条件批量给所有匹配菜谱打标签。标签在数据模型中体现为树状结构 Keyword相关迁移为 0147_keyword_to_tree见 cookbook/migrations/0147_keyword_to_tree.py导入的菜谱也会被自动归入对应的 Import N 标签树方便追溯来源。3.3 快速合并与重命名针对食材、标签和单位Tandoor 提供快速合并与重命名能力帮助清理历史数据中的重复与不一致是长期使用者的高频效率工具。3.4 从网页批量导入菜谱支持从成千上万个网站抓取菜谱前提是页面提供 schema.org 的 Recipe文档说明见 docs/features/external_recipes.md。3.5 分数与小数双格式应用同时支持**分数fractions或小数decimals**两种食材计量显示用户可通过偏好设置切换对应 UserPreference 中的 use_fractions 等字段。3.6 界面主题定制通过主题themes机制自定义界面外观仓库内置浅色/深色主题cookbook/static/themes可满足不同使用环境与视觉偏好。3.7 云存储同步支持与Dropbox 和 Nextcloud同步文件。同步层由 provider 抽象实现cookbook/provider 目录下的 dropbox.py、nextcloud.py、local.py并提供命令行同步入口cookbook/management/commands/rebuildindex.py 所在的 management/commands 目录。3.8 云端 AI 能力当前版本扩展除主页所述功能外当前仓库 READMEREADME.md还列出了 AI 辅助能力识别图片、整理菜谱步骤、查找营养信息等相关模型与配置见 cookbook/migrations/0224_space_ai_credits_balance_space_ai_credits_monthly_and_more.py 等迁移文件与 cookbook/helper/ai_helper.py。四、数据导入导出体系数据自由进出的核心通道主页将从其他菜谱管理器导入收藏列为高频需求官方为此构建了以插件式集成Integration为核心的导入导出体系。这也是全项目中文档最翔实的模块之一docs/features/import_export.md下面做源码级展开。4.1 架构Integration 基类与统一分发所有格式的导入导出都继承自同一个抽象基类Integrationcookbook/integration/integration.py。基类定义了统一的职责边界导入侧get_recipe_from_file()将任意文件对象转换为 Recipe、split_recipe_file()将包含多条菜谱的文件拆分为列表导出侧get_file_from_recipe()/get_files_from_recipes()将 Recipe 对象序列化为文件内容并在多文件时打包为 ZIP公共能力自动创建 Import N 标签归类本次导入、基于菜谱名查重的handle_duplicates()、图片处理import_recipe_image()等。具体格式的分发由工厂函数get_integration(request, export_type)完成cookbook/views/import_export.py而支持的格式清单定义在表单基类ImportExportBase中cookbook/forms.py。仓库 cookbook/integration 目录下目前维护着 27 个具体集成实现覆盖主流的菜谱管理与桌面/移动应用。实现事实虽然ImportExportBase中仍保留PDF PDF常量以兼容数据库迁移但get_integration()对 PDF 类型直接抛出NotImplementedErrorcookbook/views/import_export.py注释明确说明 pyppeteer 依赖已被移除——如需将菜谱存为 PDF请使用浏览器自带的打印功能CtrlP / CmdP。4.2 各集成能力总览下表完整列出各集成当前的能力状态✔️ 已实现❌ 未实现且不计划/不可行⌚ 尚未实现集成导入导出图片Default✔️✔️✔️Nextcloud✔️⌚✔️Mealie✔️⌚✔️Chowdown✔️⌚✔️Saffron✔️✔️❌Paprika✔️⌚✔️ChefTap✔️❌❌Pepperplate✔️⌚❌RecipeSage✔️✔️✔️Rezeptsuite.de✔️❌✔️Domestica✔️⌚✔️MealMaster✔️❌❌RezKonv✔️❌❌OpenEats✔️❌⌚Plantoeat✔️❌✔️CookBook Manager✔️⌚✔️Cooklang✔️⌚⌚CopyMeThat✔️❌✔️Mela✔️⌚✔️Cookmate✔️⌚✔️PDF (experimental)⌚️✔️✔️Gourmet✔️❌✔️Pestle✔️❌✔️说明官方明确采用导入优先于导出的策略——对大多数用户而言把既有收藏迁移进 Tandoor 是第一优先级因此各格式的导出能力⌚将随开发进度陆续补齐。WIP 提示导入导出模块相对较新大规模导出曾存在超时问题正在修复中。4.3 官方首选Default 集成Tandoor 原生格式Default 集成是内置且优先推荐的导入导出方式实现见 cookbook/integration/default.py它随新字段持续维护包含将菜谱从一套 Tandoor 安装迁移到另一套所需的全部数据其数据采用结构化 JSON便于机器读取或用于其他用途导出时每条菜谱被封装为独立的recipeId.zip内含recipe.json与可选image.*全部菜谱再打包为一个总 ZIP导入端逐层解包并读取recipe.json。重要约束使用 Default 导入时必须上传 Tandoor 导出的.zip归档文件。仅上传解压后的.json文件不被支持可能导致导入错误跨实例迁移请直接使用 ZIP 归档、不要先行解压。从源码看Default 导入通过RecipeExportSerializercookbook/serializer.py完成反序列化与落库该序列化器覆盖菜谱名称、描述、关键词、步骤、工作/等待时间、营养信息、份数与来源 URL 等核心字段。4.4 各第三方格式导入实操指南RecipeSage在 RecipeSage 中进入Settings Export Recipe Data选择EXPORT AS JSON-LD (BEST)将导出文件直接上传到 Tandoor 导入。RecipeSage 集成同时支持导出在 Tandoor 中选择 RecipeSage 类型导出再把 json 文件导入 RecipeSage 即可实现反向迁移注意导出暂不支持图片。Domestica在 Domestica 的Import/Export中选择Export Recipes将导出的文件上传到 Tandoor。Nextcloud CookbookNextcloud Cookbook 提供规范、结构化的菜谱信息导入后大多数字段可完整保留。操作步骤登录 Nextcloud Web 界面找到Recipes文件夹通常位于账号根目录下载该文件夹得到包含Recipes目录的Recipes.zip其中每个菜谱一个子目录将Recipes.zip上传到 Tandoor 导入。目录结构要求若未使用标准路径或自定义压缩方式务必保证结构一致Recipes.zip/ └── Recipes/ ├── Recipe1/ │ ├── recipe.json │ └── full.jpg └── Recipe2/ ├── recipe.json └── full.jpgMealieMealie 提供与 Nextcloud 类似的结构化数据。迁移步骤进入 Mealie 管理后台创建备份注意仅从数据管理区导出菜谱数据会导致导入不完整下载备份文件将整个.zip上传到 Tandoor 导入器。需要注意两点Mealie 存在两个版本导入器——1.0 之前的备份与1.0 及之后的备份分别对应不同的导入实现cookbook/integration/mealie1.py 与 cookbook/integration/mealie.py此外Mealie 界面不会标明营养信息是按每份还是每菜谱存储导入时需由用户指定 Tandoor 应如何处理营养数据。ChowdownChowdown 将菜谱存储在纯文本 Markdown 文件中目录名为_recipes图片存放在images目录。将这两个目录打包为.zip后导入即可Recipes.zip/ ├── _recipes/ │ ├── recipe one.md │ ├── recipe two.md │ └── ... └── images/ ├── image-name.jpg ├── second-image-name.jpg └── ...兼容性细节Chowdown 使用带下划线的_recipes目录为避免混淆导入器同时支持_recipes与recipes两种写法。Saffron在 Saffron 设置页导出菜谱将整个.zip上传到 Tandoor 即可。注意Saffron 导出不含图片图片将在导入过程中丢失。PaprikaPaprika 的导出包含一个 HTML 表示的文件夹和一个.paprikarecipes文件——该文件本质上是 gzip 压缩的 ZIP。直接上传整个文件并导入全部菜谱即可。PepperplatePepperplate 提供包含全部菜谱.txt文件的.zip包这些文件结构良好可无损导入所有数据。从 Pepperplate 导出后上传 ZIP 即可导出不含图片因此图片无法导入。ChefTapChefTap 的导出是包含cheftap_export文件夹的 ZIP其中是菜谱.txt文件。由于该格式基本无结构化规范、每次导出形态各异导入质量有限通常导入器能识别出食材其余内容归入步骤。图片不在导出内容中因此不支持。由于 ChefTap 本身无法导入这类文件Tandoor 也不会实现其导出器。MealMasterMealMaster 支持一次上传一个或多个文件格式可为.txt、.MMF或.MM。目前仅支持单列格式的食材食材的第二行注释不会被导入为注释而是并入步骤文本。无法导入的 MealMaster 文件可提交 Issue 反馈。RezKonvRezKonv Suite该格式主要用于德国菜谱管理器 RezKonv Suite。迁移方式在 RezKonv Suite 中选择Export Gesamtes Kochbuch exportieren导出菜单最后一项将生成的文件直接导入 Tandoor。Recipe KeeperRecipe Keeper 可通过其应用导出包含菜谱与图片的 ZIP 文件直接导入 Tandoor。OpenEatsOpenEats 界面不提供导出功能但可在命令行导出。在 OpenEats API 容器内执行python manage.py dumpdata recipe ingredient若采用默认安装方式可运行docker-compose -f docker-prod.yml run --rm --entrypoint sh api ./manage.py dumpdata recipe ingredient或docker exec -it openeats_api_1 ./manage.py dumpdata recipe ingredient rating recipe_groups recipe_ingredients.json将输出的 JSON 字符串保存为.json文件并上传导入格式大致如下[ { model:recipe.recipe, pk:1, fields:{ title:Tasty Chili, ... } }, ... { model:ingredient.ingredientgroup, pk:1, fields:{ title:Veges, recipe:1 } }, ... { model:ingredient.ingredient, pk:1, fields:{ title:black pepper, numerator:1.0, denominator:1.0, measurement:dash, ingredient_group:1 } } ]图片导入在 Tandoor 的recipes媒体目录通常为/opt/recipes/mediafiles下创建openeats-import文件夹将 OpenEats API 容器中/code/site-media/upload目录复制进去最终应得到/opt/recipes/mediafiles/recipes/openeats-import/upload/...路径结构。Plan to EatPlan to Eat 可导出包含全部菜谱的文本文件直接上传该文本文件即可导入所有菜谱。CookBook ManagerCookBookAppCookBook Manager 可导出包含 YAML 文件的.zip包在Settings - Backup中选择 YAML 选项导出将整个 ZIP 上传到 Tandoor。CopyMeThatCopyMeThat 可导出包含一个.html文件与图片文件夹的.zip包上传整个 ZIP 导入全部菜谱。CookmateCookmate 可导出.mcb文件直接上传到 Tandoor 导入全部菜谱。CooklangCooklang 支持导入单个.cook文件仓库配套测试见 cookbook/tests/other/test_cooklang_integration.py。目前尚不支持附加图片或导入 ZIP 文件。RecetteTekRecetteTek 导出为.rtk文件直接上传到 Tandoor 导入全部菜谱。Rezeptsuite.deRezeptsuite.de 导出为.xml文件直接上传导入。部分客户端可能导出包含.cml文件的.zip包——此时只需解压.zip并把.cml改名为.xml即可导入。MelaMela 提供多种导出格式但只有MelaRecipes格式能导出完整收藏。操作流程执行该导出得到.melarecipes文件后用解压工具如 7-Zip打开若其中仍包含.melarecipes文件则继续解压直到获得一个或多个.melarecipe文件将需要导入的.melarecipe文件全部上传到 Tandoor 并开始导入。PDF基于 pyppeteer 的 PDF 导出已被移除。如需将菜谱保存为 PDF请使用浏览器内置打印功能CtrlP / CmdP。Gourmet导入器针对 Gourmet.grmt文件缺少食材单位的问题设计为接收包含.htm与.jpg的.zip包在 Gourmet 中导出为 HTML 并压缩生成文件夹。不支持导入菜单由于.grmt格式存在问题也不支持导出。Pestle从 Pestle 应用设置中点击 Export选择 Pestle Recipe Format得到mm-dd-yyyy.pestle文件用于导入。可导入的信息包括名称、描述、份数、等待时间、工作时间、分类关键词、标签、食材作为附加步骤、步骤、营养、图片与来源。其他字段评分、作者、备注、菜系、视频将丢失。导出不支持因为 Pestle 需要图片 URL而导入数据中不包含。4.5 ZIP 导入的安全边界与性能参数由于多数格式以 ZIP 为载体基类Integrationcookbook/integration/integration.py内置了完整的解压安全防护对应环境变量定义于 recipes/settings.py环境变量默认值作用MAX_ZIP_FILE_COUNT2000ZIP 内最大文件数量MAX_ZIP_TOTAL_SIZE500MB解压后总大小上限MAX_ZIP_FILE_SIZE10MB单个文件解压后大小上限MAX_ZIP_NESTING_DEPTH2嵌套 ZIP 的最大层数超过任一限制导入器会中止并给出明确错误提示有效防止zip bomb式恶意或误操作文件拖垮服务器。4.6 命令行导入导出除 Web 界面外仓库还提供两个 Django management 命令manage.py import与manage.py export见 cookbook/management/commands/import.py 与 cookbook/management/commands/export.py。二者分别继承 Django 内置的loaddata/dumpdata命令并额外以scopes_disabled包装从而绕过空间的django-scopes隔离限制方便在脚本化迁移、备份恢复等场景下跨空间读写数据。五、部署与运维要点Tandoor 强调使用 Docker 轻松搭建仓库提供的部署资源包括Docker Compose 示例见 docs/install/docker.md以及docs/install下针对反向代理nginx、traefik、apache等场景的 compose 模板Kubernetes完整 K8s 资源清单位于 docs/install/k8sConfigMap、Secret、PVC、StatefulSet、Deployment、Ingress 等Unraid / Synology分别提供安装指南docs/install/unraid.md、docs/install/synology.mdNginx 配置示例仓库自带 nginx/conf.d/Recipes.conf 与模板文件 http.d/Recipes.conf.template。典型部署依赖 PostgreSQL 数据库全文检索与 TrigramSimilarity 依赖其能力前端为 Vue 3 编译产物由后端静态托管。生产环境建议按 docs/system/configuration.md 配置环境变量其中上文提到的MAX_ZIP_*系列与EXPORT_FILE_CACHE_DURATION默认 600 秒控制导出文件的缓存时长recipes/settings.py均在此统一管理。六、项目现状与路线图主页文档docs/index.md坦诚地说明了项目所处阶段应用在过去一年经历了快速迭代引入了 Vue.js 等新技术功能大量扩张的同时部分细节与技术实现的品质仍有提升空间。因此除持续更新的功能与里程碑见仓库 Issues Milestones外未来主要目标包括改善 UI当前设计风格不一致许多页面可用但观感欠佳拥抱开放数据与开放系统为所有相关菜谱管理系统补齐导入器与导出器前端工程化清理将所有 JavaScript 库迁移到包管理器统一管理清理早期积累的技术债提升测试质量与覆盖率改进既有测试并扩充用例完善文档为全部功能与使用场景补齐文档并增加应用内帮助。项目最初的诞生动机是索引、打标签和搜索个人收藏的数字化PDF菜谱随着功能持续叠加如今已成长为功能全面的菜谱管理系统。结语Tandoor Recipes 的价值在于把菜谱收藏 → 膳食计划 → 购物清单 → 分享协作这条生活化链路完整打通同时以插件式集成架构cookbook/integration对 20 余种第三方格式提供导入能力让用户的既有数据资产可以低成本迁移。对于希望深入了解实现细节的读者推荐继续阅读导入导出全量文档docs/features/import_export.md网页抓取导入文档docs/features/external_recipes.md集成基类实现cookbook/integration/integration.py原生格式序列化cookbook/serializer.pyRecipeExportSerializer各平台部署指南docs/install。【免费下载链接】recipesApplication for managing recipes, planning meals, building shopping lists and much much more!项目地址: https://gitcode.com/GitHub_Trending/re/recipes创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考