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

如何在Django应用中通过GitHub API获取指定用户指定月份的Pull Requests?

在Django中通过GitHub API获取指定用户特定月份的Pull Requests

嘿,我来帮你搞定这个需求!要在Django应用里拉取指定用户某月份创建的PR,咱们得先理清GitHub API的正确用法,再一步步实现代码逻辑。

第一步:搞懂GitHub API的正确姿势

你给出的示例用了/issues端点,但其实GitHub的Pull Requests是特殊类型的Issue,用搜索API或者专门的/pulls端点会更精准。这里推荐用搜索API,因为它支持灵活的时间范围和多条件筛选。

比如要获取myrepo/example仓库中,person_name在2018年1月创建的所有PR,正确的API查询逻辑是:

GET /search/issues?q=repo:myrepo/example+is:pr+creator:person_name+created:2018-01-01..2018-01-31

参数说明:

  • repo:myrepo/example:锁定目标仓库
  • is:pr:只筛选Pull Requests(排除普通Issue)
  • creator:person_name:指定PR的创建者
  • created:YYYY-MM-DD..YYYY-MM-DD:限定创建时间的闭区间范围

⚠️ 重要提醒:一定要用**个人访问令牌(PAT)**认证请求!未认证请求每小时只有60次限额,用PAT能提升到5000次。创建PAT时,只需给repo(私有仓库)或public_repo(公开仓库)权限即可。

第二步:在Django中实现请求逻辑

首先确保安装了requests库(用来发送HTTP请求):

pip install requests

接下来写一个工具函数,封装API请求和分页处理(GitHub API结果默认分页,最多每页100条):

import requests
from datetime import datetime, timedelta
from django.conf import settings

def get_user_monthly_prs(repo_owner, repo_name, username, year, month):
    # 自动计算当月的起始和结束日期
    start_date = f"{year}-{month:02d}-01"
    # 计算当月最后一天,避免手动处理不同月份天数的麻烦
    next_month_first_day = datetime(year, month, 1) + timedelta(days=32)
    end_date = next_month_first_day.replace(day=1) - timedelta(days=1)
    end_date_str = end_date.strftime("%Y-%m-%d")

    # 构造API请求参数
    api_url = "https://api.github.com/search/issues"
    query_params = {
        "q": f"repo:{repo_owner}/{repo_name}+is:pr+creator:{username}+created:{start_date}..{end_date_str}",
        "per_page": 100,  # 每页最多返回100条,减少分页请求次数
    }
    # 认证头,把你的PAT配置在Django的settings.py里
    request_headers = {
        "Authorization": f"token {settings.GITHUB_PAT}",
        "Accept": "application/vnd.github.v3+json"
    }

    all_prs = []
    current_url = api_url
    # 处理分页,直到没有下一页
    while current_url:
        response = requests.get(current_url, params=query_params, headers=request_headers)
        # 主动抛出HTTP错误,方便后续处理
        response.raise_for_status()
        response_data = response.json()
        all_prs.extend(response_data["items"])

        # 解析Link头,获取下一页链接
        link_header = response.headers.get("Link")
        current_url = None
        if link_header:
            for link in link_header.split(", "):
                if 'rel="next"' in link:
                    current_url = link.split("; ")[0].strip("<>")
                    query_params = {}  # 下一页链接已包含所有参数,无需重复传递

    return all_prs

第三步:在Django视图中调用工具函数

你可以写一个视图来返回处理后的PR数据,比如以JSON格式返回:

from django.http import JsonResponse
from .utils import get_user_monthly_prs  # 假设工具函数在utils.py里

def user_monthly_prs(request):
    # 这里可以从请求参数中动态获取仓库、用户、年月,示例先写死
    repo_owner = "myrepo"
    repo_name = "example"
    username = "person_name"
    target_year = 2018
    target_month = 1

    try:
        prs = get_user_monthly_prs(repo_owner, repo_name, username, target_year, target_month)
        # 提取需要的字段简化返回结果
        simplified_prs = [
            {
                "title": pr["title"],
                "pr_url": pr["html_url"],
                "created_time": pr["created_at"],
                "state": pr["state"]
            } for pr in prs
        ]
        return JsonResponse({"pull_requests": simplified_prs})
    except requests.exceptions.RequestException as e:
        return JsonResponse({"error": str(e)}, status=500)

额外注意事项

  • 速率限制处理:GitHub API会返回X-RateLimit-Remaining和X-RateLimit-Reset响应头,你可以在代码中添加逻辑,当剩余请求次数不足时等待重置时间。
  • 错误捕获:务必处理网络错误、认证失败、仓库不存在等异常情况,避免应用崩溃。
  • PAT安全:不要把PAT硬编码在代码里,放在Django的settings.py中,并且确保敏感配置不提交到版本库。

内容的提问来源于stack exchange,提问作者Awaish Kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:49:29