【发布时间】:2010-12-30 05:40:47
【问题描述】:
我正在创建一个类似于 reddit 和黑客新闻的网站,其中包含链接和投票数据库。我正在实施黑客新闻的流行度算法,事情进展顺利,直到实际收集这些链接并显示它们。算法很简单:
Y Combinator 的黑客新闻: 人气 = (p - 1) / (t + 2)^1.5` 选票除以年龄因素。 哪里` p :来自用户的投票(积分)。 t :自提交以来的时间,以小时为单位。 p 减 1 以否定提交者的投票。 年龄因子是(以小时为单位的提交时间加 2)的 1.5 次方。因子是(以小时为单位的提交时间加 2)的 1.5 次方。我在 Complex ordering in Django 上问了一个非常相似的问题,但我没有考虑我的选择,而是选择了一个并尝试让它工作,因为这就是我使用 PHP/MySQL 的方式,但我现在知道 Django 做的事情有很大不同。
我的模型看起来(完全)像这样
class Link(models.Model):
category = models.ForeignKey(Category)
user = models.ForeignKey(User)
created = models.DateTimeField(auto_now_add = True)
modified = models.DateTimeField(auto_now = True)
fame = models.PositiveIntegerField(default = 1)
title = models.CharField(max_length = 256)
url = models.URLField(max_length = 2048)
def __unicode__(self):
return self.title
class Vote(models.Model):
link = models.ForeignKey(Link)
user = models.ForeignKey(User)
created = models.DateTimeField(auto_now_add = True)
modified = models.DateTimeField(auto_now = True)
karma_delta = models.SmallIntegerField()
def __unicode__(self):
return str(self.karma_delta)
我的看法:
def index(request):
popular_links = Link.objects.select_related().annotate(karma_total = Sum('vote__karma_delta'))
return render_to_response('links/index.html', {'links': popular_links})
现在,从我之前的问题来看,我正在尝试使用排序函数来实现算法。该问题的答案似乎认为我应该将算法放在选择中然后排序。我将对这些结果进行分页,因此我认为如果不抓取所有内容,我就无法在 python 中进行排序。关于如何有效地做到这一点的任何建议?
编辑
这还行不通,但我认为这是朝着正确方向迈出的一步:
from django.shortcuts import render_to_response
from linkett.apps.links.models import *
def index(request):
popular_links = Link.objects.select_related()
popular_links = popular_links.extra(
select = {
'karma_total': 'SUM(vote.karma_delta)',
'popularity': '(karma_total - 1) / POW(2, 1.5)',
},
order_by = ['-popularity']
)
return render_to_response('links/index.html', {'links': popular_links})
这个错误输出到:
Caught an exception while rendering: column "karma_total" does not exist
LINE 1: SELECT ((karma_total - 1) / POW(2, 1.5)) AS "popularity", (S...
编辑 2
更好的错误?
TemplateSyntaxError: Caught an exception while rendering: missing FROM-clause entry for table "vote"
LINE 1: SELECT ((vote.karma_total - 1) / POW(2, 1.5)) AS "popularity...
我的 index.html 很简单:
{% 块内容 %} {% for link in links %} 业力提升 {{ 链接.karma_total }} 业力下降 {{ 链接.title }} 由 {{ link.user }} 在 {{ link.created }} 发布到 {{ link.category }} {% 空的 %} 没有链接 {% endfor %} {% endblock 内容 %}编辑 3 非常接近!同样,所有这些答案都很棒,但我专注于一个特定的答案,因为我觉得它最适合我的情况。
from django.db.models import Sum
from django.shortcuts import render_to_response
from linkett.apps.links.models import *
定义索引(请求): popular_links = Link.objects.select_related().extra( 选择 = { '受欢迎程度': '(SUM(links_vote.karma_delta) - 1) / POW(2, 1.5)', }, 表 = ['links_link', 'links_vote'], order_by = ['-人气'], ) return render_to_response('links/test.html', {'links': popular_links})
运行此程序时,我遇到一个错误,讨厌我缺乏按值分组。具体来说:
TemplateSyntaxError at /
Caught an exception while rendering: column "links_link.id" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: ...karma_delta) - 1) / POW(2, 1.5)) AS "popularity", "links_lin...
不确定为什么我的 links_link.id 不会在我的 group by 但我不知道如何更改我的 group by,django 通常会这样做。
【问题讨论】:
-
嗯,吃光了 HTML。啊,好吧,我最不用担心了。
标签: python django algorithm postgresql