我有一個模型方法,可以在我的模型中使用HN排名算法來計算投票的得分,該算法還可以緩存每個得分。 calculate_score()
是這裏關注的主要內容。Django:order_by API json值或緩存對象
class Submission(models.Model):
submission_type = models.CharField(_('Submission Type'),
max_length=255,
choices=tuple([(media.name.lower(), media.value) for media in MediaTypes]),
blank=False)
title = models.CharField(_('Title'), max_length=100, blank=False)
url = models.URLField(_('Link'), blank=False)
description = models.TextField(_('Description'))
flagged = models.BooleanField(_('Is Flagged for Review'), default=False)
user = models.ForeignKey(User, related_name='user_submissions')
thumbnail = models.ImageField()
date_submitted = models.DateTimeField(default=timezone.now)
by_votes = VoteCountManager()
objects = models.Manager()
def __str__(self):
return self.submission_type + ': ' + self.title
def get_absolute_url(self):
return reverse('submit_detail', args=[
str(self.submission_type),
str(self.id),
])
def get_vote(self):
"""
Returns the number of votes associated with a particular submission
:return: int
"""
return self.submission_votes.count()
def calculate_score(self):
"""
This is a variation of the HN ranking algorithm
:return: score
"""
secs_in_hour = float(60 * 60)
g = 1.2
delta = timezone.now() - self.date_submitted
item_hour_age = delta.total_seconds()/secs_in_hour
votes = self.submission_votes.count() - 1
score = votes/pow((item_hour_age + 2), g)
cached = cache.get('s{0}'.format(self.pk))
if not cached:
cache.set('s{0}'.format(self.pk), score, 30)
return score
我使用我的序列化模型djangorestframework
:
class SubmissionSerializer(serializers.HyperlinkedModelSerializer):
score = serializers.SerializerMethodField('rank')
class Meta:
model = Submission
def rank(self, obj):
return obj.calculate_score()
我有兩種方法,我想我能解決我的問題,但我不知道該怎麼辦它們中的,我不確定哪一個是最好的。因爲我爲每個提交的文件緩存了score
。我試圖責令提交在ListView像這樣從緩存中拉:
class SubmissionList(ListView):
model = Submission
def get_queryset(self):
return super(SubmissionHotList, self).get_queryset().annotate(
score=cache.get('s{0}'.format(x) for x in Submission.pk)
votes=models.Count('submission_votes'),
).order_by(
'-score', '-votes',
)
但是我發現order_by
僅適用於數據庫級,我不得不創建一個數據庫字段所計算的得分,如果可能,我希望避免這種情況。我的其他可能性是在我的API中使用Submission
這個ListView
中的序列化數據,但是我不確定API是否僅適用於外部應用程序,或者我是否可以在生成API的相同應用程序中使用它們。
我想我的問題是。讓緩存對象按特定順序列出每個提交,還是使用API來完成此操作會更好?如果我使用API,我怎麼能解析和訂購ListView中的JSON數據,同時保持votes
作爲輔助訂購機制?
損失任何性能這是完美的!非常感謝。 – joshchandler 2014-10-08 15:36:07