我有一长串的链接,我使用下面的代码,总票数,提交的,通常的东西吐出来,但我不是100%如何确定当前登录用户已投票的链接或不。我知道如何从我的视野内做到这一点,但我是否需要改变我的下面的视图代码,或者我可以使用模板的工作方式来确定它?Django:确定用户是否投了票
我已阅读Django Vote Up/Down method,但我不太明白发生了什么事情(并且不需要任何文字说明)。
模型(片段):
class Link(models.Model):
category = models.ForeignKey(Category, blank=False, default=1)
user = models.ForeignKey(User)
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
url = models.URLField(max_length=1024, unique=True, verify_exists=True)
name = models.CharField(max_length=512)
def __unicode__(self):
return u'%s (%s)' % (self.name, self.url)
class Vote(models.Model):
link = models.ForeignKey(Link)
user = models.ForeignKey(User)
created = models.DateTimeField(auto_now_add=True)
def __unicode__(self):
return u'%s vote for %s' % (self.user, self.link)
意见(摘录):
def hot(request):
links = Link.objects.select_related().annotate(votes=Count('vote')).order_by('-created')
for link in links:
delta_in_hours = (int(datetime.now().strftime("%s")) - int(link.created.strftime("%s")))/3600
link.popularity = ((link.votes - 1)/(delta_in_hours + 2)**1.5)
if request.user.is_authenticated():
try:
link.voted = Vote.objects.get(link=link, user=request.user)
except Vote.DoesNotExist:
link.voted = None
links = sorted(links, key=lambda x: x.popularity, reverse=True)
links = paginate(request, links, 15)
return direct_to_template(
request,
template = 'links/link_list.html',
extra_context = {
'links': links,
})
以上观点实际上完成我需要什么,但我认为是一个可怕的低效的方式。这导致了可怕的n + 1查询,因为它代表了33个查询包含29个链接的页面,而最初我只有4个查询。我真的更喜欢用Django的ORM或至少.extra()来做到这一点。
有什么建议吗?
编辑
@Gabriel赫利
我试图重新您的回答,我会有不同的结果,让我告诉雅我得到了什么。
views.py
links = Link.objects.select_related().extra(
select={
'votes': 'COUNT(links_vote.id)',
'voted': 'SELECT COUNT(links_vote.id) FROM links_vote WHERE links_vote.user_id = 1 AND links_vote.link_id = links_link.id',
},
tables = ['links_vote']
)
models.py
class Vote(models.Model):
link = models.ForeignKey(Link)
user = models.ForeignKey(User)
created = models.DateTimeField(auto_now_add=True)
class Meta:
unique_together = ('link', 'user')
def __unicode__(self):
return u'%s vote for %s' % (self.user, self.link)
但它返回一个错误:
subquery uses ungrouped column "links_link.id" from outer query
LINE 1:... E links_vote.user_id = 1 AND links_vote.link_id = links_link ...
所生成的查询看起来是(精确地)是这样的:
SELECT (SELECT COUNT(links_vote.id) FROM links_vote WHERE links_vote.user_id = 1 AND links_vote.link_id = links_link.id) AS "voted", "links_link"."id", "links_link"."category_id", "links_link"."user_id", "links_link"."created", "links_link"."modified", "links_link"."url", "links_link"."name", "links_category"."id", "links_category"."name", "auth_user"."id", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."password", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."is_superuser", "auth_user"."last_login", "auth_user"."date_joined" FROM "links_link" INNER JOIN "links_category" ON ("links_link"."category_id" = "links_category"."id") INNER JOIN "auth_user" ON ("links_link"."user_id" = "auth_user"."id") , "links_vote"
我使用PostgreSQL我知道爱GROUP BY但我不是如何纠正这种100%。 。
EDIT 2(主要进展)
链接= Link.objects.select_related()注释(票=计数( '投票'))的额外( 选择= { # '投票': 'SELECT COUNT()FROM links_vote WHERE links_vote.user_id =%s AND links_vote.link_id = links_link.id'%(request.user.id), #'voteed':''%(request.user.id), ''voteed':'SELECT CASE WHEN links_vote.user_id =%s THEN 1 ELSE 0 END'%(request.user.id), #'voteed':'SELECT COUNT()FROM links_vote WHERE links_vote.link_id = links_link.id和links_vote.u ser_id =%s'%(request.user.id), }, 其中= ['links_link.id = links_vote.link_id'], )。ORDER_BY(“ - 创建”)
*从这里应用补丁的漏洞后,这仅适用于(http://code.djangoproject.com/ticket/11916)
我如此接近发现最后一块,我需要确定用户是否已经投票。 ..
我有几个问题不适合在这里,看看我上面的编辑。虽然谢谢!我觉得这让我走上了正轨。 – TheLizardKing 2010-05-13 21:16:34