PYTHON中分组groups
from itertools import groupby
def get_cm_months_report(start_date, end_date):
"""上一次Check out时间和最近一次Check in时间,并且相减。取所有小于等于365天的单据。
"""
csv_header = [
"Serial Number",
"Stock Code",
"Group",
"Last Check Out Date",
"Check In Date",
]
csv_fields = [
"serial_number",
"stock_code",
"group",
"last_check_out",
"check_in_date",
]
status_list = [RepairOrder.STATUS.CHECKED_IN, RepairOrder.STATUS.IN_PROCESS, RepairOrder.STATUS.WAITING_FOR_ENDORSEMENT, RepairOrder.STATUS.WAITING_FOR_SIC, RepairOrder.STATUS.WAITING_FOR_JOB_COMPLETED, RepairOrder.STATUS.COMPLETE, RepairOrder.STATUS.FORCE_COMPLETE]
cm_repair_order_id_list = RepairOrder.objects.filter(mtce_type=RepairOrder.MTCE_TYPE.CM,status__in=status_list, deleted=False).values_list("id", flat=True)
repair_order_part_query = RepairOrderPart.objects.filter(repair_order_id__in=cm_repair_order_id_list).order_by("stock_code", "serial_no", "-last_check_in")
new_repair_order_part_list: list[CmMonthsDict] = []
# 根据 (stock_code, serial_no) 分组
repair_order_parts_grouped = groupby(repair_order_part_query, key= lambda x: (x.stock_code, x.serial_no))
# 迭代处理每个分组
new_repair_order_part_list = []
for (stock_code, serial_no),group in repair_order_parts_grouped:
group = list(group) # 转换成列表以便处理
if len(group) >= 2:
last_check_in = group[0].last_check_in
last_check_out = group[1].last_check_out
if last_check_out and last_check_in and group[0].last_check_out == None:
days_diff = abs((last_check_in - last_check_out).days)
if days_diff <= 365:
new_repair_order_part_list.append({
"serial_number": serial_no,
"stock_code": stock_code,
"group": group[0].repair_order.workgroup,
"last_check_out": last_check_out,
"check_in_date": last_check_in,
})
# 过滤check_in日期
if start_date:
start_date = timezone.make_aware(datetime.strptime(start_date, "%Y/%m/%d"), timezone.get_current_timezone())
new_repair_order_part_list = [part for part in new_repair_order_part_list if part["check_in_date"] > start_date]
if end_date:
end_date = timezone.make_aware(datetime.strptime(end_date, "%Y/%m/%d"), timezone.get_current_timezone()) + timedelta(days=1)
new_repair_order_part_list = [part for part in new_repair_order_part_list if part["check_in_date"] < end_date]
for index, data in enumerate(new_repair_order_part_list):
new_repair_order_part_list[index]["check_in_date"] = timezone.localtime(data["check_in_date"]).strftime("%Y/%m/%d %H:%M:%S")
new_repair_order_part_list[index]["last_check_out"] = timezone.localtime(data["last_check_out"]).strftime("%Y/%m/%d %H:%M:%S")
# 写入csv
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="CM Months Report.csv"'
writer = csv.writer(response)
writer.writerow(csv_header)
for obj in new_repair_order_part_list:
row = (str(obj[field]) for field in csv_fields)
writer.writerow(row)
return r