我正在开发一个博客web应用程序,我想监控一篇文章的浏览量。我决定使用post detail视图来计数。为了防止特定用户的计数器递增,我将只允许登录用户计数,并且用户只能计数一次。
这是我的帖子模型
class Post(models.Model):
title = models.CharField(max_length=150)
content = models.TextField(max_length=3000, null=True, blank=True)
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
viewers = models.TextField(default="", null=True, blank=True)
numViews = models.IntegerField(default=0)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk': self.pk})
字符串
我基本上是使用一个字段'观众'来跟踪用户已经计数和'numviews'作为计数器。
我的views.py函数
class PostDetailView(DetailView):
model = Post
def get(self, request, *args, **kwargs):
# increment post views whenever request is made
postObject = self.get_object()
user = request.user
if postObject.viewers == None:
postObject.viewers = ""
postObject.save()
if user.is_authenticated and user.username not in postObject.viewers:
# increment
postObject.numViews += 1
postObject.save()
# add username to viewers list
postObject.viewers+=user.username
postObject.save()
return super().get(request, *args, **kwargs)
型
在views函数中,我检查用户名是否已经附加到viewers字符串中,否则附加它并递增计数器。有没有更有效的方法来做到这一点?在博客获得数千次浏览的情况下,它将是一个非常长的用户名字符串。
2条答案
按热度按时间vvppvyoh1#
在博客获得数千次浏览的情况下,它将是一个非常长的用户名字符串。
它不仅效率低下,而且可能导致错误的结果。如果您有三个用户
foo
,bar
和foobar
,那么如果foo
访问页面,bar
访问页面,那么如果foobar
访问页面,则不会考虑他们的视图。另一个问题是这里可能有 * 竞争条件 :如果两个用户几乎同时访问同一个帖子,则数据库可能最终只更新了 * 一个 * 用户的对象,因此就像另一个用户从未访问过该页面一样。
通常情况下,您可以通过*
ManyToManyField
**[Django-doc]来确定谁查看了该帖子:字符串
然后我们可以将视图实现为:
型
oprakyz72#
我用@Willem货车Onsem修改了我的代码,它似乎工作正常。在postdetail视图中,只进行了self.user -> self.request.user的更正。此外,查看者的数量可以通过((post.viewers.count}}在html模板中的post对象中访问,也可以通过{{object.num_views}}在详细视图模板中访问