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

Django API中functools.partial结合map出现参数重复值错误求助

Django REST Framework中map+partial传参报错:TypeError: get_counts() got multiple values for argument 'id'

问题场景

在DRF API端点中尝试用map结合functools.partial传递额外参数,测试代码正常运行,但API代码触发参数冲突错误。

测试代码(正常运行)

>>> tt
[(datetime.datetime(2023, 4, 1, 0, 0), datetime.datetime(2023, 4, 10, 0, 0)), (datetime.datetime(2023, 4, 10, 0, 0), datetime.datetime(2023, 4, 1, 0, 0))]

>>> def t(d1: datetime.datetime, d2: datetime.datetime, i: int):
...  print(f"First: {d1.strftime('%Y-%m-%d')} & Second: {d2.strftime('%Y-%m-%d')} w/ ID: {i}")

>>> list(map(partial(t, i=10), *tt))
First: 2023-04-01 & Second: 2023-04-10 w/ ID: 10
First: 2023-04-10 & Second: 2023-04-01 w/ ID: 10
[None, None]

API代码(报错位置标注)

from rest_framework.decorators import api_view
from rest_framework.response import Response
import datetime
import functools
from .models import Entity, OtherEntity

@api_view(["GET"])
def get_registration_counts(request, start: str, stop: str) -> Response:
    date_format = "%Y-%m-%d"
    # 验证start和stop参数有效性,无效则返回HTTP 400
    datasets = []
    def get_counts(d1: datetime.datetime, d2: datetime.datetime, id: int) -> int:
        r = Entity.objects.filter(some_date__gte=d1, some_date__lte=d2, fk_id=id)
        c = r.count()
        return c
    # 计算日期范围
    dates = [(some_start_date1, some_end_date1), (some_start_date2, some_end_date2)]
    some_values = OtherEntity.objects.filter(active=1).values("id", "name")
    for v in some_values:
        # 报错位置:
        counts = list(map(functools.partial(get_counts, id=v["id"]), *dates)) 
        datasets.append(counts)
        # ...其他逻辑
    # ...其他逻辑

报错信息

Exception Type: TypeError
Exception Value: get_counts() got multiple values for argument 'id'

问题原因

你混淆了map的两种用法,测试代码与API代码的map调用逻辑完全不匹配:

  1. 测试代码逻辑:
    *tt将列表拆分为两个独立可迭代对象,map并行遍历这两个对象,每次取两个元素作为t的前两个位置参数,第三个参数i由partial以关键字参数绑定,无参数冲突。
  2. API代码逻辑错误:
    你实际需求是遍历dates中的每个(start, end)元组,调用get_counts(start, end, id=v["id"]),但错误使用*dates导致:
    • *dates将dates拆分为多个独立可迭代对象(每个元组对应一个)
    • map并行遍历这些对象,每次传入N个位置参数(N为dates的长度)
    • 若N>2,第三个位置参数会被当作id的位置参数传入,而partial已经以关键字参数绑定了id,导致参数重复传递,触发错误。

解决方法

根据你的实际需求(遍历dates中的每个元组并传入id),调整map用法:

方法1:用lambda拆包元组

counts = list(map(lambda dt: get_counts(dt[0], dt[1], id=v["id"]), dates))

方法2:结合partial与lambda拆包

bound_get_counts = functools.partial(get_counts, id=v["id"])
counts = list(map(lambda dt: bound_get_counts(*dt), dates))

方法3:调整参数顺序适配partial(若需匹配测试代码逻辑)

修改get_counts参数顺序,将id放在首位,再用zip(*dates)对齐参数:

def get_counts(id: int, d1: datetime.datetime, d2: datetime.datetime) -> int:
    r = Entity.objects.filter(some_date__gte=d1, some_date__lte=d2, fk_id=id)
    return r.count()

counts = list(map(functools.partial(get_counts, v["id"]), *zip(*dates)))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 01:07:13