我有这样的看法:
def profile (request):
articles = Post.thing.all()
newSet = set()
def score():
for thing in articles:
Val = some calculation...
....
newSet.update([(thing,Val)])
score()
context = {
'articles': articles.order_by('id'),
'newSet':newSet,
}
return render(request,'my_profile/my_profile.html',context)
结果是一个查询集,如下所示:
set([(<thing: sfd>, 1), (<thing: quality>, 0), (<thing: hello>, -1), (<thing: hey>, 4), (<thing: test>, 0)
我现在正在尝试按给定的值对集合进行排序,因此它是一个以最高值开头的列表,但是当我这样做时newSet.order_by/filter/split/join
自'set' object has no attribute join/filter/split
年以来它不起作用.
任何人都可以给我一个提示如何对查询集进行排序,我自己找不到任何有用的东西。
我需要在视图中解决它,因此它不能/不应该在模型中完成。感谢您的任何建议。
结果是一个查询集,看起来像这样
实际上这是一个set
(python内置类型),而不是QuerySet
(django的orm类型)。
set
是一种无序集合类型。要"排序"它,您首先必须将其变成list
- 这实际上就像newlist = list(newset)
一样简单, 然后,您可以使用newlist.sort()
就地对列表进行排序。由于您希望此列表按其项目第二个元素进行排序,因此您需要使用key
参数告诉sort
您想要排序的内容:
newlist.sort(key=lambda item: item[1])
或者你可以改变你的score()
函数来存储(score, obj)
元组,在这种情况下,list.sort()
自然会做正确的事情(它会在你的元组的第一个项目上排序)。
newSet.add()
来代替使用单个项目的列表调用newSet.update()
,即:
def score():
for thing in articles:
val = some calculation...
....
newset.add((thing, val))
# or if you don't want to specify a callback
# for `list.sort()`:
# newset.add((val, thing))
最后:你真的需要set
吗?为什么不从一开始就使用list
?
我想你可能会在集合、列表和查询集之间有点混淆?集合是无序的,而列表不是。集合不会公开上面列出的方法(筛选、order_by、拆分、联接)。QuerySet 是一个特定于 Django 的类,它有许多有用的方法。
我认为将newSet
制作为元组列表,然后通过使用list.sort(key=lambda x: x[1])
value
对该列表进行排序会更简单。
但是,如果您对 val 的计算符合条件,我建议您使用 annotate,然后取消newDict
或newSet
,只需传回文章的查询集,这将更简单,可能更快,并且可以通过使用articles.order_by('value')
进行排序。如果你发布val
的计算,我会试着告诉你这是否可行。