Django如何向utils.py传递用户信息并在视图中控制Calendar类查询集
问题根源
你之前定义的get_queryset没有生效,是因为你写的Calendar类内部直接硬编码执行了Class的查询,完全没有使用视图层返回的查询集结果,两个逻辑完全脱节。
解决方案(完全满足视图层控制查询集的需求,无需在utils中处理用户逻辑)
第一步:修改utils.py中的Calendar类,将查询集改为入参
class Calendar(HTMLCalendar): # 其余原有方法保持不变,仅修改formatmonth方法 def formatmonth(self, events, withyear=True): # 删掉类内部原来的events查询逻辑,直接使用外部传入的查询集 cal = f'<table border="0" cellpadding="0" cellspacing="0" class="calendar">\n' cal += f'{self.formatmonthname(self.year, self.month, withyear=withyear)}\n' cal += f'{self.formatweekheader()}\n' for week in self.monthdays2calendar(self.year, self.month): cal += f'{self.formatweek(week, events)}\n' return cal
如果有其他旧代码调用了formatmonth方法,可以给events加默认值做兼容:def formatmonth(self, events=None, withyear=True):,未传参时保留原来的默认查询逻辑即可。
第二步:修改视图层代码,打通查询集传递链路
class CalendarView(LoginRequiredMixin, generic.ListView): model = Class template_name = 'leads/calendar.html' def get_queryset(self): d = get_date(self.request.GET.get('month', None)) # 所有查询规则完全在视图层控制,按用户角色返回对应结果 if self.request.user.is_student: return Class.objects.filter(date__year=d.year, date__month=d.month).exclude(student=None) elif self.request.user.is_teacher: return Class.objects.exclude(student=None) # 其他角色可自定义返回规则,默认返回空 return Class.objects.none() def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) d = get_date(self.request.GET.get('month', None)) cal = Calendar(d.year, d.month) # 把视图层生成的查询集直接传入Calendar的渲染方法 html_cal = cal.formatmonth(events=self.get_queryset(), withyear=True) context['calendar'] = mark_safe(html_cal) context['prev_month'] = prev_month(d) context['next_month'] = next_month(d) return context
逻辑说明
Calendar类只保留纯渲染日历的功能,和业务逻辑完全解耦,后续调整日历样式不需要碰业务查询代码- 所有用户权限、查询规则的控制完全放在视图层,符合你不想在utils中处理用户逻辑的需求
- 后续要调整查询规则,只需要修改视图的
get_queryset方法即可,不需要改动utils代码
内容的提问来源于stack exchange,提问作者coderDcoder
相关产品推荐
相关产品推荐

