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
相关产品推荐
相关产品推荐

