查询由外键链接的 Django 模型以获得完整的查询集,计算喜欢的帖子

Querying Django Models linked by a Foreign Key to get a complete Query set, counting liked posts

提问人:Gidgey 提问时间:10/25/2023 最后编辑:Gidgey 更新时间:10/25/2023 访问量:24

问:

这是一个 CS50 Pset - 网络 - 我正在努力解决这个问题,除了这一点之外,一切都已经完成了

我想我把自己困在了一个角落里,我有 4 个不同的模型,其中 3 个与这个问题有关,用户、帖子和 LikeMatrix。LikeMatrix 对用户模型(用户)和帖子模型(帖子)都使用外键,它是一个记录用户喜欢什么帖子的矩阵,因为我无法让我最初的想法与用户和帖子模型之间的多对多链接一起工作。(如果我再做一次,我会做不同的)。我让我的 Js 工作,我的 API 工作,除了拼图的最后一块之外,其他东西都在工作,以计算 LikeMatrix 模型中每个帖子的点赞数,然后将其发送到 index.html

我在 views.py 中运行一个查询,该查询从 Posts 中提取数据并将其发送到模板/Queryset 中以编制索引.html,请参阅下面的屏幕截图,了解它在屏幕上的外观。我敢肯定有很多更专业的方法来做我正在做的事情,但我正在学习,独自一人做,这已经花了我几个星期的时间......任何关于在我粘贴这个问题时看起来更好的建议将不胜感激。

models.py

class User(AbstractUser):    
    pass


class Posts(models.Model):   #notes for future, use singular in naming for admin reasons.
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="author")
    content = models.CharField(max_length=280)  #twitter style
    timestamp = models.DateTimeField(auto_now_add=True) #django docs - may be incorrect options    

    def __str__(self):
        return f' number {self.id} post, Posted by {self.user} '

class LikeMatrix(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="liker")
    post = models.ForeignKey(Posts, on_delete=models.CASCADE, related_name="post")

    def __str__(self):
        return f"{self.user} likes {self.post} post"

索引.html

它在下面迭代并填充 index.html 中的帖子(对不起,那里有评论让我跟踪我所处的位置)。除了镜头中的点赞数外,这一切都会根据屏幕截图填充,它只是我在编程时的一个静态占位符。我需要做的是能够计算每个帖子的点赞数,我相信它会计算 LikesMatrix 中每个帖子的用户数。

{% for post in pagePosts %}

            <div class="col-12">
                <div class="row">
                    <!--<h3 class="username" href="{% url 'profile' user_id=user.id %}">   @{{post.user}}</h3>-->
                    <h3 ><a class="username" href="{% url 'profile' user_id=post.user.id %}">@{{post.user }}</a></h3>  <!-- font size to be sorted -->
                    <h3 class="edit"> Edit</h3>
                    <h3 class="content">  {{post.id}}</h3>

                    <h3 class="content" id="content_{{post.id}}"> {{post.content}}</h3>
                    <h3 class="date"> {{post.timestamp}}</h3>

                    <div>
                    {% if user == post.user %}
                      <h5 class="likes"> <label id="likes">&#128151  <label id="postLikes">{{post.likes}}</h5>
                      <!--this is just a red heart and a number - no onclick here;>-->

                    {% elif post.id in likedPostsUser %}
                    <div>
                      <h5 class="likes2" id="clickLikes_{{post.id}}" onclick="clickLikesRoutine({{post.id}}, 'True')">💗</h5><label id="likesNum">{{post.likes}}</label>

                    </div>
                    {% else %}
                      <h5 class="likes2" id="clickLikes_{{post.id}}" onclick="clickLikesRoutine({{post.id}}, 'True')">🤍</h5><label id="likesNum">{{post.likes}}</label>


                    {% endif %}
                    </div>


                    <div>
                        <!--Edit Modal Bootstrap>-->
                        <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#edit_text_modal_{{ post.id }}">
                            Edit
                          </button>



我尝试过 Django Count()、python count()、annotate、select_related,我花了几个小时试图锻炼如何提取和分组这些数据。我可以为帖子 <QuerySet [1, 11, 11, 11, 11, 13, 14]> 获得一个包含整数 ID 的 Queryset,它告诉我帖子 11 已被点赞 3 次,1,13,14 次都被点赞一次,我还可以通过标题和用户名获得点赞帖子的完整列表以及谁喜欢它们, 但无法在下面解决这个问题。我不需要一个完整的解决方案,但请提供一些指导来帮助我理解这个过程。心下的数字 1 只是一个静态占位符,当我让它运行时,它将被替换为此数据,谢谢

this gets me the queryset above
likedPosts = LikeMatrix.objects.all().values_list('post_id', flat=True) 


this is my all post query I send to index.html
allPosts = Posts.objects.all().order_by("id").reverse() 



I have now made some progress using len() and .filter() to get back the number of times a posts id is in a queryset, my current thoughts are now to use distinct() to filter the existing queryset and then loop the remainer values through the equation below and append to a new list, im sure there are easier ways but Im working on it, thanks

current_vote = len(LikeMatrix.objects.select_for_update().filter(post='14'))
    print(current_vote)

enter image description here

django django-queryset cs50

评论


答:

0赞 Mess 10/25/2023 #1

如果您尝试按帖子的总点赞数对帖子进行分组,并假设您正在将查询集转换为简单列表,如 [1, 11, 11, 11, 13, 14] 示例所示。您可以简单地执行以下操作:

sample = [1,11,11,11,13,14]
grouped = {} # key will be the post id and the value will be total occurences (likes)
for post_id in set(sample): # set will convert the list with duplicate to unique values.
  grouped[str(post_id)] = sample.count(post_id)

您最终会得到以下内容:

{'1': 1, '11':3, ...}