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

Django多变量组合问题:首页展示随机与最新博客报错

解决Django中exclude(id__in)触发类型错误的问题

嘿,这个错误我之前踩过坑!问题根源很明确:你传给exclude(id__in=data1)的data1是Blog对象的列表,但id__in查询需要的是id值的集合(比如整数列表),Django尝试把Blog对象转换成整数时自然就报错了。

错误原因拆解

你的原代码里:

data1 = sorted(Blog.objects.all(), key=lambda x: random.random())[:4]
data2 = Blog.objects.exclude(id__in=data1).order_by('-id')[:6]

data1是4个Blog实例组成的列表,当执行exclude(id__in=data1)时,Django会遍历data1里的每个对象,试图把它转成int类型(因为id是整数字段),但Blog对象既不是字符串、数字也不是字节,所以触发了int() argument must be a string, a bytes-like object or a number, not 'Blog'这个错误。

修正方案(两种可选)

方案1:先获取随机id,再查询对象(更高效)

如果博客数量较多,这种方式能避免把所有Blog对象加载到内存,性能更好:

import random
from itertools import chain

# 从所有博客id中随机选4个
random_ids = random.sample(list(Blog.objects.values_list('id', flat=True)), 4)
# 获取对应的4篇随机文章
data1 = Blog.objects.filter(id__in=random_ids)
# 排除随机文章,取最新6篇
data2 = Blog.objects.exclude(id__in=random_ids).order_by('-id')[:6]
# 合并结果
results = list(chain(data1, data2))

注意:如果需要保持data1的随机顺序,上面的data1是按id排序的,你可以再对它做一次随机排序:data1 = sorted(data1, key=lambda x: random.random())

方案2:先拿随机对象,再提取id(保留原逻辑)

如果想保留你原来先获取随机对象的逻辑,只需要额外提取id列表即可:

import random
from itertools import chain

# 获取4篇随机文章(保持随机顺序)
data1 = sorted(Blog.objects.all(), key=lambda x: random.random())[:4]
# 提取这些文章的id列表
random_ids = [blog.id for blog in data1]
# 排除这些id,取最新6篇
data2 = Blog.objects.exclude(id__in=random_ids).order_by('-id')[:6]
# 合并结果
results = list(chain(data1, data2))

小提示

  • 使用values_list('id', flat=True)可以直接获取纯id的列表,比加载完整对象更轻量
  • 当数据量较大时,random.sample比sorted(..., key=random.random)更高效,因为后者需要把所有对象加载到内存排序

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:24:28