You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django中实现登录/会话用户搜索关键词的次数统计

实现Django搜索关键词的次数统计功能

要实现同一用户(登录/会话)重复搜索关键词时的次数统计,你需要先给搜索记录模型添加计数字段,再修改视图逻辑用原子操作更新计数,具体步骤如下:

1. 更新search_keywords模型

首先给模型新增一个用于统计搜索次数的字段,默认值设为1(第一次搜索直接记1次):

from django.db import models
from django.contrib.auth.models import User

class search_keywords(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
    session_id = models.CharField(max_length=255, null=True, blank=True)
    search_word = models.CharField(max_length=255)
    # 新增搜索计数字段,默认值为1
    search_count = models.IntegerField(default=1)
    updated_at = models.DateTimeField(auto_now=True)  # 可选:记录最后一次搜索时间

    # 可选:添加唯一约束,避免同一用户/会话重复创建相同关键词的冗余记录
    class Meta:
        unique_together = (('user', 'search_word'), ('session_id', 'search_word'))

修改完模型后,执行数据库迁移命令:

python manage.py makemigrations
python manage.py migrate

2. 修改视图中的搜索记录逻辑

替换你原来的判断创建逻辑,用Django的update_or_create方法配合F()表达式做原子更新,既能避免并发场景下的计数错误,又能简化代码:

from django.db.models import F

def get_queryset(self):
    query = self.request.GET.get('q')
    if query:
        # 确保未登录用户的会话ID存在,避免空标识导致统计失效
        session_id = self.request.session.session_key
        if not session_id:
            self.request.session.create()
            session_id = self.request.session.session_key

        if self.request.user.is_authenticated:
            # 登录用户:按user+search_word匹配,存在则计数+1,不存在则创建新记录
            obj, created = search_keywords.objects.update_or_create(
                user=self.request.user,
                search_word=query,
                defaults={
                    'session_id': session_id,  # 可选:同步更新会话ID
                    'search_count': F('search_count') + 1
                }
            )
        else:
            # 未登录用户:按session_id+search_word匹配,更新计数
            obj, created = search_keywords.objects.update_or_create(
                session_id=session_id,
                search_word=query,
                defaults={'search_count': F('search_count') + 1}
            )

        # 以下是原有的搜索逻辑,保持不变
        search_vector = (
            SearchVector('title', weight='A') +
            SearchVector('description', weight='B')
        )
        search_query = SearchQuery(query)
        return items.objects.annotate(
            rank=SearchRank(search_vector, search_query)
        ).filter(rank__gt=0.1).order_by('-rank')
    return items.objects.none()

关键说明:

  • update_or_create:自动根据指定条件查找记录,存在则更新defaults内的字段,不存在则创建新记录,省去了手动判断exists()的代码。
  • F('search_count') + 1:直接在数据库层面执行加法操作,属于原子更新,能避免多用户同时搜索同一关键词时出现的计数不准问题。
  • 会话ID处理:确保未登录用户的会话标识有效,保证统计逻辑的完整性。

内容的提问来源于stack exchange,提问作者Href Link

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 01:20:13