You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django网站中展示GitHub仓库的README.md文件内容

Django站点展示GitHub仓库README实现方案

整体逻辑分为三步:拉取指定仓库的README原始Markdown内容、将Markdown转为安全的HTML内容、在Django模板中渲染展示。

依赖安装

需要三个第三方库:

  • requests:发起HTTP请求拉取README内容
  • markdown:将Markdown文本转换为HTML
  • bleach:过滤转换后HTML中的危险标签,避免XSS安全问题
    执行安装命令:
    pip install requests markdown bleach

核心代码实现

1. 视图函数编写

视图负责参数校验、内容拉取、格式转换、安全过滤,示例代码如下:

import requests
import markdown
import bleach
from django.http import Http404
from django.template import loader
from django.core.cache import cache

# 配置HTML标签白名单,仅放行排版需要的安全标签
ALLOWED_TAGS = [
    'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'ul', 'ol', 'li',
    'pre', 'code', 'blockquote', 'a', 'img', 'strong', 'em', 'hr',
    'table', 'thead', 'tbody', 'tr', 'th', 'td', 'br'
]
# 配置标签允许的属性
ALLOWED_ATTRIBUTES = {
    'a': ['href', 'title'],
    'img': ['src', 'alt', 'title']
}

def repo_readme(request, owner, repo):
    # 校验传入的所有者、仓库名参数合法性,拦截特殊字符
    valid_char = lambda s: s.replace('-', '').replace('_', '').replace('.', '').isalnum()
    if not valid_char(owner) or not valid_char(repo):
        raise Http404("仓库参数不合法")
    
    # 优先读缓存,避免频繁请求GitHub触发限流
    cache_key = f"repo_readme_{owner}_{repo}"
    safe_html = cache.get(cache_key)
    if not safe_html:
        readme_raw = None
        # 依次尝试main、master两个最常见的默认分支拉取README
        for branch in ['main', 'master']:
            try:
                resp = requests.get(
                    f"https://raw.githubusercontent.com/{owner}/{repo}/{branch}/README.md",
                    timeout=5,
                    headers={"User-Agent": "Mozilla/5.0 (compatible; ReadmePreviewBot/1.0)"}
                )
                if resp.status_code == 200:
                    readme_raw = resp.text
                    break
            except requests.exceptions.RequestException:
                continue
        if not readme_raw:
            raise Http404("未找到对应仓库的README文件")
        
        # Markdown转HTML,开启代码块、表格扩展
        html_content = markdown.markdown(
            readme_raw,
            extensions=['fenced_code', 'tables', 'codehilite']
        )
        # 过滤危险标签与属性
        safe_html = bleach.clean(
            html_content,
            tags=ALLOWED_TAGS,
            attributes=ALLOWED_ATTRIBUTES,
            strip=True
        )
        # 写入缓存,有效期30分钟
        cache.set(cache_key, safe_html, 60*30)

    # 传入模板渲染
    template = loader.get_template('readme_view.html')
    context = {
        'owner': owner,
        'repo': repo,
        'readme_content': safe_html
    }
    return template.render(context, request)

2. 路由配置

在应用的urls.py中添加路由映射,支持通过URL传入所有者和仓库名参数:

from django.urls import path
from . import views

urlpatterns = [
    path('repo/<str:owner>/<str:repo>/readme/', views.repo_readme, name='repo_readme'),
]

3. 模板编写

在templates目录下新建readme_view.html,渲染过滤后的README内容,可自定义样式匹配站点风格:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>{{ owner }}/{{ repo }} 项目说明</title>
    <style>
        .readme-wrap {
            max-width: 920px;
            margin: 2rem auto;
            padding: 0 1rem;
            line-height: 1.6;
        }
        pre {
            background: #f6f8fa;
            padding: 1rem;
            border-radius: 6px;
            overflow-x: auto;
        }
        code {
            background: #f6f8fa;
            padding: 0.2rem 0.4rem;
            border-radius: 3px;
            font-family: Consolas, Monaco, monospace;
        }
        pre code {
            padding: 0;
            background: transparent;
        }
        blockquote {
            border-left: 4px solid #dfe2e5;
            padding-left: 1rem;
            color: #6a737d;
            margin: 1rem 0;
        }
        table {
            border-collapse: collapse;
            width: 100%;
            margin: 1rem 0;
        }
        th, td {
            border: 1px solid #dfe2e5;
            padding: 0.5rem 1rem;
        }
        img {
            max-width: 100%;
        }
    </style>
</head>
<body>
    <div class="readme-wrap">
        <h1>{{ owner }} / {{ repo }}</h1>
        <hr>
        {{ readme_content|safe }}
    </div>
</body>
</html>

注意事项

  • 缓存必须配置:GitHub公开接口有请求频率限制,加缓存既能降低被限流的概率,也能提升页面加载速度,缓存时长可根据自己的需求调整。
  • 私有仓库适配:如果需要展示私有仓库的README,在requests请求头中添加Authorization字段,传入GitHub个人访问令牌即可,令牌不要硬编码在代码中,建议存放在环境变量或Django私密配置里。
  • 分支兼容:如果需要覆盖非main/master默认分支的场景,可以先请求仓库元信息获取默认分支名,再拼接README拉取地址,常规场景下两个分支兜底足够使用。
  • 安全过滤不可省略:直接渲染未经过滤的Markdown转义结果会存在XSS风险,必须通过白名单方式过滤危险标签和属性。

内容的提问来源于stack exchange,提问作者Tom Cohen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 04:36:23