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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 07:39:22