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

Django侧边栏点击链接后Submissions列表消失问题排查

问题描述

我正在开发一个Django项目,需在侧边栏展示Submissions列表。侧边栏嵌入基础模板main.html,其他模板均继承该模板。首页时侧边栏能正常显示所有Submissions,但点击侧边栏中的某个Submission后,页面跳转正确,但侧边栏仅显示被点击的Submission,其余条目全部消失。

相关代码

Models.py

from django.db import models
from users.models import UserProfile

# Create your models here.
class ResearchWork(models.Model):
    name = models.CharField(max_length=100)
    description = models.TextField()
    
    def __str__(self):
        return self.name
    

class Assignment(models.Model):
    student = models.ForeignKey(UserProfile, related_name='student_assignment', on_delete=models.CASCADE)
    teacher = models.ForeignKey(UserProfile, related_name='teacher_assignment', on_delete=models.CASCADE)
    is_accepted = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)
    text = models.TextField(blank=True)
    
    
    def __str__(self):
        return f"Assignment for {self.student.user.username} with {self.teacher.user.username}"
    

class Submission(models.Model):
    assignment = models.ForeignKey(Assignment, on_delete=models.CASCADE)
    SEMESTER_CHOICES = (
        ('1', 'Semester 1'),
        ('2', 'Semester 2'),
        ('3', 'Semester 3'),
        ('4', 'Semester 4'),
        ('5', 'Semester 5'),
        ('6', 'Semester 6'),
        ('7', 'Semester 7'),
        ('8', 'Semester 8'),
    )
    semester = models.CharField(max_length=100, null=True, choices=SEMESTER_CHOICES)
    research_work = models.ForeignKey(ResearchWork, on_delete=models.CASCADE, null=True)
    created_at = models.DateTimeField(auto_now_add=True, null=True)
    
    
    def __str__(self):
        research_work_name = "No Research Work Assigned" if self.research_work is None else self.research_work.name
        return f"{research_work_name} - for student {self.assignment.student.user.username} in semester - {self.semester}"

Context Processor

from base.models import Submission

def user_profile_pk(request):
    context = {}
    if request.user.is_authenticated:
        user_profile_pk = request.user.userprofile.pk
        context['user_profile_pk'] = user_profile_pk
        
        student = request.user.userprofile
        submissions = Submission.objects.filter(assignment__student=student)
        context['submissions'] = submissions
    else:
        context['user_profile_pk'] = None
        context['submissions'] = None
    print(f"Submissions for {student}: {submissions}")
    return context

Settings.py

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            BASE_DIR / 'templates'
            ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                'users.context_processors.user_profile_pk',
            ],
        },
    },
]

模板遍历代码

{% for submission in submissions %}
        <li class="nav-item">
          <a
            class="nav-link"
            href="{% url 'research-work-detail' rw_id=submission.research_work.id semester=submission.semester subm_id=submission.id %}"
            ><span class="nav-icon"></span>{{submission.research_work.name}} -
            Сем.{{submission.semester}}</a
          >
        </li>

        {% endfor %}

Urls.py

urlpatterns = [
    path('login/', views.loginPage, name='login'),
    path('home/', views.home, name='home'),
    path('student/<str:pk>/', views.student_home, name='student-home'),
    path('research-work/<int:rw_id>/<str:semester>/<int:subm_id>/', views.research_work_detail, name='research-work-detail'),
    path('topics/<int:rw_id>/<int:topic_id>/<int:subm_id>/', views.upload_page, name='upload-page'),
    path('upload-file/<int:subm_id>/<int:topic_id>/', views.upload_file, name='upload-file'),
    path('choose-teacher/<int:student_id>/', views.choose_teacher, name='choose-teacher'),
]
urlpatterns += static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)
urlpatterns += static(settings.STATIC_URL, document_root = settings.STATIC_ROOT)

views.py - research_work_detail

def research_work_detail(request, rw_id, semester, subm_id):
    research_work = get_object_or_404(ResearchWork, pk=rw_id)
    submissions = Submission.objects.filter(research_work=research_work, semester=semester)
    submission = get_object_or_404(Submission, pk=subm_id)
    topics = Topic.objects.filter(research_work=research_work)
    context =   {'research_work': research_work, 'submissions':submissions, 'topics': topics, 'submission_id':submission.id }
    return render(request, 'users/topics.html', context=context)
问题原因

核心是变量名冲突:上下文处理器会给所有模板传递当前用户的所有Submissions,但在research_work_detail视图中,你重新定义了submissions变量,它的值是Submission.objects.filter(research_work=research_work, semester=semester)——这个查询只会返回当前详情页对应的同ResearchWork、同Semester的Submission(通常只有一条)。

Django模板渲染时,视图传递的上下文变量优先级高于上下文处理器的变量,所以侧边栏遍历submissions时,实际使用的是视图传递的窄范围数据,导致只显示一条。

修复方案

推荐以下两种修复方式:

方式一:重命名视图中的变量(最优)

将视图里的submissions变量改为其他名称,避免覆盖上下文处理器的变量:

def research_work_detail(request, rw_id, semester, subm_id):
    research_work = get_object_or_404(ResearchWork, pk=rw_id)
    # 重命名变量,避免与上下文处理器的submissions冲突
    current_submissions = Submission.objects.filter(research_work=research_work, semester=semester)
    submission = get_object_or_404(Submission, pk=subm_id)
    topics = Topic.objects.filter(research_work=research_work)
    context = {
        'research_work': research_work, 
        'current_submissions': current_submissions, 
        'topics': topics, 
        'submission_id': submission.id
    }
    return render(request, 'users/topics.html', context=context)

这样模板侧边栏的{% for submission in submissions %}会正常使用上下文处理器传递的用户所有Submissions,视图所需的特定数据则用current_submissions调用即可。

方式二:在视图中显式传递用户所有Submissions

如果视图逻辑需要同时使用用户所有Submissions和当前详情页的Submissions,也可以在视图中重新获取并传递(但不如方式一高效,因为上下文处理器已经做了这个工作):

def research_work_detail(request, rw_id, semester, subm_id):
    research_work = get_object_or_404(ResearchWork, pk=rw_id)
    current_submissions = Submission.objects.filter(research_work=research_work, semester=semester)
    submission = get_object_or_404(Submission, pk=subm_id)
    topics = Topic.objects.filter(research_work=research_work)
    
    # 复用上下文处理器的逻辑,获取用户所有Submissions
    if request.user.is_authenticated:
        student = request.user.userprofile
        submissions = Submission.objects.filter(assignment__student=student)
    else:
        submissions = None
    
    context = {
        'research_work': research_work, 
        'current_submissions': current_submissions, 
        'topics': topics, 
        'submission_id': submission.id,
        'submissions': submissions
    }
    return render(request, 'users/topics.html', context=context)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 23:06:00