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

如何基于用户组过滤Django表单下拉选项?

Alright, let's tackle this problem of filtering form dropdown options based on the user's group. Since you already have the in_group template tag and core models/forms/views in place, here's a robust, secure approach (backend-side filtering is key here—frontend-only tweaks can be easily bypassed by savvy users):

Step 1: Modify the Form to Filter Choices Based on User Group

We'll update your ChangeTaskForm to accept a user parameter during initialization, then filter the status field's choices based on which group the user belongs to.

First, assuming your GoalStatus model looks something like this:

from django.db import models

class GoalStatus(models.Model):
    GOALS_TYPE = (
        ('Draft', 'Draft'),
        ('Review', 'Review'),
        ('Verified', 'Verified'),
        ('Done', 'Done'),
    )
    status = models.CharField(max_length=20, choices=GOALS_TYPE)
    # other fields...

Update the ChangeTaskForm to add group-based filtering:

from django import forms
from .models import GoalStatus

class ChangeTaskForm(forms.ModelForm):
    class Meta:
        model = GoalStatus
        fields = ['status']

    def __init__(self, *args, **kwargs):
        # Extract the user from kwargs before passing to parent class
        self.user = kwargs.pop('user', None)
        super().__init__(*args, **kwargs)

        # Only filter if we have a logged-in user
        if self.user and self.user.is_authenticated:
            # Define group-specific allowed status options
            group_status_rules = {
                'DEVELOPER': ['Verified', 'Done'],
                # Add rules for other groups as needed
                'MANAGER': ['Review', 'Verified', 'Done'],
                'ADMIN': [choice[0] for choice in GoalStatus.GOALS_TYPE]  # All options
            }

            # Collect allowed statuses based on user's groups
            allowed_statuses = set()
            for group_name, status_list in group_status_rules.items():
                if self.user.groups.filter(name=group_name).exists():
                    allowed_statuses.update(status_list)

            # Fallback: if user isn't in any defined group, set default allowed statuses
            if not allowed_statuses:
                allowed_statuses = ['Draft', 'Review']  # Adjust this to your needs

            # Filter the form field's choices
            self.fields['status'].choices = [
                (status, label) for status, label in GoalStatus.GOALS_TYPE
                if status in allowed_statuses
            ]

Step 2: Pass the User to the Form in Your View

Update your move_goals view to pass the current user when initializing the form:

from django.shortcuts import render, redirect
from .forms import ChangeTaskForm

def move_goals(request):
    if request.method == 'POST':
        # Pass request.user to the form for filtering
        form = ChangeTaskForm(request.POST, user=request.user)
        if form.is_valid():
            form.save()
            # Redirect to your desired page after success
            return redirect('task_list')  # Replace with your URL name
    else:
        # Initialize form with user for initial dropdown filtering
        form = ChangeTaskForm(user=request.user)

    return render(request, 'task.html', {'form': form})

Step 3: Render the Form in Your Template

You can now render the form normally in task.html—the dropdown will already be filtered based on the user's group. If you want to add group-specific UI tweaks, you can use your existing in_group tag:

{% load your_custom_tags %} <!-- Load your custom template tags here -->

<form method="POST">
    {% csrf_token %}
    
    <!-- Optional: Add group-specific messaging -->
    {% if user|in_group:"DEVELOPER" %}
        <p>You can only select Verified or Done statuses.</p>
    {% endif %}

    <!-- Render the form field (already filtered!) -->
    {{ form.as_p }}

    <button type="submit">Update Task</button>
</form>

Key Notes

  • Security: By filtering choices in the form (backend), we ensure users can't submit invalid status values even if they manipulate the frontend HTML.
  • Flexibility: The group_status_rules dictionary makes it easy to add/modify rules for other groups later.
  • Multiple Groups: If a user belongs to multiple groups, the code above merges all allowed statuses from those groups—adjust the logic if you want to prioritize a specific group instead.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:00:43