Django投票系统:按登录用户部门过滤投票选项方案咨询
解决方案
你的核心问题在于:页面展示选项的逻辑完全没用到视图里的过滤逻辑,模板直接调用了campanie.participanti_set.all,而你之前修改的是POST提交时的代码(和展示无关)。下面是正确实现步骤:
1. 修改视图逻辑(views.py)
区分GET/POST请求,在GET请求时过滤掉当前用户同部门的参与人,同时在POST提交时验证投票对象是否符合规则:
@authenticate def votare_campanie(request): campanie = get_object_or_404(Campanie) # 获取当前登录用户的部门(request.user就是UserVot实例) user_dep = request.user.departament # 过滤参与人:排除与当前用户同部门的选项 participanti = campanie.participanti_set.all() if user_dep: # 避免用户无部门时过滤出错 participanti = participanti.exclude(dep_participant=user_dep) if request.method == 'POST': try: # 从过滤后的集合中获取投票对象,防止用户手动提交同部门选项 participant_votat = participanti.get(pk=request.POST['participanti']) except (KeyError, Participanti.DoesNotExist): return render(request, 'campanievot/campanie.html', { 'campanie': campanie, 'participanti': participanti, 'error_message': "Trebuie sa votezi cel putin un coleg", }) else: participant_votat.votes += 1 participant_votat.save() messages.success(request, "Multumim pentru feedback!") return redirect('campanievot:index') # GET请求时,将过滤后的参与人传给模板 return render(request, 'campanievot/campanie.html', { 'campanie': campanie, 'participanti': participanti, })
2. 修改模板遍历逻辑(template.html)
把模板中直接遍历campanie.participanti_set.all改成遍历视图传入的participanti:
<form action=" {% url 'campanievot:votare_campanie' %} " method="post" > {% csrf_token %} {% for p in participanti %} <label for="p{{ forloop.counter }}" class="form-check custom-icon mt-2 mb-4" role="button"> <input type="radio" name="participanti" class="form-check-input" id="p{{ forloop.counter }}" value="{{ p.id }}"> <span class="form-check-label"> <span class="content"> <span for="p{{ forloop.counter }}" class="heading mb-1 d-block lh-1-25">{{p.nume_participant }} {{ p.dep_participant }}</span> <!-- <span class="d-block text-small text-muted">04.05.2021 - 12:00 </span> --> </span> </span> </label> {% endfor %} {{form.media}} <button class="m-auto btn btn-icon btn-icon-start btn-primary mb-1" type="submit"> <i data-acorn-icon="send"></i> <span>Trimite</span> </button> </form>
关键说明
- 之前的错误修改是在
try块中,这部分是处理用户提交投票的逻辑,和页面展示选项完全无关; - 必须将过滤后的查询集主动传给模板,而不是让模板直接调用模型的关联集合;
- POST请求时从过滤后的集合中获取投票对象,能防止用户通过手动修改表单提交同部门的选项,增加安全性。
内容的提问来源于stack exchange,提问作者Robert Murariu
相关产品推荐
相关产品推荐

