未读帖子 Django

Posted

技术标签:

【中文标题】未读帖子 Django【英文标题】:Unread posts Django 【发布时间】:2020-05-22 11:35:17 【问题描述】:

我已经使用 Django(功能非常简单的博客)构建了一个博客,我希望能够在我的博客中只向用户显示他尚未阅读的帖子。 我有 10,000 多个帖子,我想在用户每次登录他还没有看到的随机帖子时向他展示/ 我是 Django 的新手,我不确定我应该以正确的方式去做。 我有 Post 模型:

class Post(models.Model):
author = models.ForeignKey('auth.User',on_delete=models.CASCADE)
title = models.CharField(max_length=200)
text = models.TextField()
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)

def publish(self):
    self.published_date = timezone.now()
    self.save()

def approve_comments(self):
    return self.comments.filter(approved_comment=True)

def get_absolute_url(self):
    return reverse("post_detail",kwargs='pk':self.pk)

def __str__(self):
    return self.title

谢谢!

【问题讨论】:

显示已读帖子的UserPost 之间的关系在哪里?只需添加(m2m 关系),然后通过排除已存在关系的帖子来过滤帖子。然后你需要选择随机帖子,解释here @dirkgroten 我没有那种关系,因为这是我要求的——我问的是如何建立这种关系。谢谢! 【参考方案1】:

您必须记录用户以及他阅读了哪些帖子。就这样

class UserReadPost(models.Model):
    user = models.ForeignKey(User, releated_name='user_read_posts')
    post = models.ForeignKey(Post, releated_name='posts_read_by_users')
    read_at = models.DateTimeField(auto_now=True)

每次用户阅读某个帖子时,您都必须在此表中添加一条记录。您可以像这样获取用户尚未阅读的所有帖子。

from django.db.models import OuterRef, Subquery, Exists

post_read_status = UserReadPost.objects.filter(post=OuterRef('post'), user=current_user_object)
Post.objects.all().annotate(has_read=Exists(post_read_status)).exclude(has_read=True).order_by('?')

这可以使用ManyToManyField 来完成,但添加您自己的表格将使您能够检查该用户何时阅读该特定帖子。

【讨论】:

请注意,order_by('?') 是一种非常低效的选择随机元素的方法。在大桌子上会很慢。请参阅this 以获得更有效的方法。如果您想要 5 个帖子,请对随机索引进行 5 次查询,这将比使用 order_by('?') 的一次查询要快。 @dirkgroten 我刚刚写了如何做到这一点。感谢开导。【参考方案2】:

你应该使用ManyToManyField:

class Post(models.Model):
author = models.ForeignKey('auth.User',on_delete=models.CASCADE)
title = models.CharField(max_length=200)
text = models.TextField()
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
read_users = models.ManyToManyField(User) # Add this line

def publish(self):
    self.published_date = timezone.now()
    self.save()

def approve_comments(self):
    return self.comments.filter(approved_comment=True)

def get_absolute_url(self):
    return reverse("post_detail",kwargs='pk':self.pk)

def __str__(self):
    return self.title

【讨论】:

以上是关于未读帖子 Django的主要内容,如果未能解决你的问题,请参考以下文章

DjangoDjango 如何使用 Django设置的日志?

Djangodjango配置信息

DjangoDjango 文件下载最佳实践

DjangoDjango模块创建应用程序

DjangoDjango 如何支持 分组查询统计?

DjangoDjango Debug Toolbar调试工具配置