Django视图传参至JS实现点击发件人筛选展示对应消息
前端交互实现方案
一、HTML模板结构调整
在你的CSM/home.html模板中,调整左右两侧的HTML结构,给发件人标签和消息项添加标识属性,方便JS筛选:
<!-- 左侧发件人列表 --> <div class="sender-list"> <!-- 添加"全部消息"选项,默认选中 --> <span class="sender-tag active" data-sender-id="all">全部消息</span> <!-- 遍历所有唯一发件人,用ifchanged避免重复显示 --> {% for message in messages|dictsort:"sender"|dictsortreversed:"date_created" %} {% ifchanged message.sender %} <span class="sender-tag" data-sender-id="{{ message.sender.id }}"> {{ message.sender.username }} <!-- 显示未读消息标记 --> {% if message.sender.id in unreaded %} <span class="unread-badge">!</span> {% endif %} </span> {% endifchanged %} {% endfor %} </div> <!-- 右侧消息显示区域 --> <div class="messages-container"> {% for message in messages %} <div class="message-item" data-sender-id="{{ message.sender.id }}"> <!-- 针对阿拉伯语消息调整排版 --> <div class="message-content {% if message.id in ar_messages_ids %}arabic-text{% endif %}"> <p><strong>{{ message.sender.username }}</strong> | {{ message.date_created }}</p> <p>{{ message.message }}</p> {% if not message.is_read %} <span class="unread-mark">未读</span> {% endif %} </div> </div> {% empty %} <p>暂无消息</p> {% endfor %} </div>
二、JavaScript交互逻辑
在模板底部添加JS代码,实现点击发件人筛选消息的功能:
// 获取所有发件人标签和消息项 const senderTags = document.querySelectorAll('.sender-tag'); const messageItems = document.querySelectorAll('.message-item'); // 给每个发件人标签绑定点击事件 senderTags.forEach(tag => { tag.addEventListener('click', function() { // 移除所有标签的激活状态 senderTags.forEach(t => t.classList.remove('active')); // 标记当前点击的标签为激活状态 this.classList.add('active'); const targetSenderId = this.getAttribute('data-sender-id'); // 筛选并显示对应消息 messageItems.forEach(item => { if (targetSenderId === 'all') { item.style.display = 'block'; } else { if (item.getAttribute('data-sender-id') === targetSenderId) { item.style.display = 'block'; } else { item.style.display = 'none'; } } }); }); });
三、CSS样式优化
添加基础样式,提升交互体验:
/* 左侧发件人列表 */ .sender-list { width: 250px; border-right: 1px solid #eee; padding: 10px; } .sender-tag { display: block; padding: 8px 12px; margin-bottom: 5px; border-radius: 4px; cursor: pointer; transition: background-color 0.2s; } .sender-tag.active { background-color: #007bff; color: white; } .unread-badge { background-color: #dc3545; color: white; font-size: 12px; padding: 2px 5px; border-radius: 50%; margin-left: 5px; } /* 右侧消息区域 */ .messages-container { flex: 1; padding: 15px; } .message-item { margin-bottom: 15px; padding: 10px; border-bottom: 1px solid #eee; } .arabic-text { direction: rtl; text-align: right; } .unread-mark { background-color: #ffc107; color: #212529; font-size: 12px; padding: 2px 6px; border-radius: 3px; margin-left: 8px; }
四、视图优化建议(可选)
为了减少前端模板的逻辑复杂度,建议在视图中提前获取唯一发件人列表:
@authenticated_user def home(request): employee = Employee.objects.get(user=request.user) try: allMessages = Messages.objects.filter(reciever=request.user).order_by('-date_created') # 获取唯一发件人ID列表 unique_sender_ids = allMessages.values_list('sender', flat=True).distinct() # 原有阿拉伯语消息逻辑不变 arabic_messages_ids = [] for message in allMessages: if re.search(r'[\u0600-\u06FF]', message.message): arabic_messages_ids.append(message.id) unread_messages = Messages.objects.filter(reciever=request.user, is_read=False).values_list('id', flat=True) except Messages.DoesNotExist: allMessages = [] unique_sender_ids = [] unread_messages = [] arabic_messages_ids = [] return render(request, "CSM/home.html", { 'employee': employee, 'messages': allMessages, 'unreaded': unread_messages, 'ar_messages_ids': arabic_messages_ids, 'unique_sender_ids': unique_sender_ids })
对应模板发件人列表可简化为:
<div class="sender-list"> <span class="sender-tag active" data-sender-id="all">全部消息</span> {% for sender_id in unique_sender_ids %} {% with sender=User.objects.get(id=sender_id) %} <span class="sender-tag" data-sender-id="{{ sender_id }}"> {{ sender.username }} {% if sender_id in unreaded %} <span class="unread-badge">!</span> {% endif %} </span> {% endwith %} {% endfor %} </div>
内容的提问来源于stack exchange,提问作者SpeedyKabal
相关产品推荐
相关产品推荐

