首页 > 解决方案 > 如何在 Django 中获得另一个特定用户的批准来更新表单?

问题描述

我想在我的 Django 项目中创建一个基本的审批系统。在这个系统中有几个等级,但对于这个问题,我只使用LeadManager。我创建了forms这个表格,它代表limits.

只能Lead填写这些表格。但我想要的是当潜在客户更新表单时,它不应该在未经Manager' 批准的情况下显示。我怎样才能做到这一点?

批准/models.py

class DoaTable(models.Model):
    LIMITS = (
        ('Low Risk', 'Low Risk'),
        (...),
        ('Strict Credit Check', 'Strict Credit Check'),
        ('No Credit Check', 'No Credit Check'),
    )

    RANKS = (
        ('Analyst', 'Analyst'),
        ('Senior Analyst', 'Senior Analyst'),
        ('Lead', 'Lead'),
        ('Manager', 'Manager'),
        ('...Officer'),
    )
    rank = models.CharField(max_length=200, choices=RANKS)
    risk = models.CharField(max_length=200, choices=LIMITS)
    limit = models.FloatField()
    comp_name = models.ForeignKey(CompanyProfile, on_delete=models.CASCADE, null=True)

用户/模型.py

class UserProfile(AbstractUser):

...
password = models.CharField(max_length=250)
email = models.EmailField(max_length=254)
rank = models.CharField(max_length=200)
...

class Rank(models.Model):
    rank_name = models.CharField(max_length=200)
    company = models.ForeignKey(CompanyProfile, on_delete=models.CASCADE, null=True, unique=False)

此模型中的排名与 Doa 表排名相同。我们假设用户等级是该场景的 Lead 和 Manager。

批准/forms.py

class DoaTableForm(forms.ModelForm):
    class Meta:
        model = DoaTable
        fields = ('rank', 'risk', 'limit',)

class UpdateDoaTableForm(forms.ModelForm):
    class Meta:
        model = DoaTable
        fields = ('limit',)

批准/views.py

def update_limit(request, id):
    limiting = get_object_or_404(DoaTable, id=id)
    form = UpdateDoaTableForm(request.POST or None, request.FILES or None, instance=limiting)
    limiting_item = DoaTable.objects.filter(id=id)

    if form.is_valid():
        form.save()
        return redirect('approvals:update_limit_list')

    context = {
        'form': form,
        'limiting_item': limiting_item
    }

    return render(request, 'limitUpdate.html', context)

标签: pythondjango

解决方案


1.如何使用您当前的架构来做到这一点

向您的 DoaTable 模型添加一个新列以反映它是否应该显示,并且仅在 doatable.should_display 为时显示在您的视图中True

批准/models.py

class DoaTable(models.Model):
    # ....
    should_display = models.BooleanField(default=False)
    rank = models.CharField(max_length=200, choices=RANKS)
    # ...

然后覆盖您的 ModelForm__init__()以接受当前用户和clean()方法来检查排名:

批准/forms.py

from django.core.exceptions import ValidationError
# ...
class UpdateDoaTableForm(forms.ModelForm):
    class Meta:
        model = DoaTable
        fields = ('limit',)

    def __init__(self, *args, user, **kwargs):
        super().__init__(*args, **kwargs)
        self.user = user

    def clean(self):
        cleaned_data = super().clean()
        if self.user.rank != "Lead": # BAD: hardcoded value
            raise ValidationError(
                    "You do not have the required rank."
            )
        return cleaned_data # Always return the cleaned data

request.user在您的视图中传递:

批准/views.py

def update_limit(request, id):
    # ...
    form = UpdateDoaTableForm(request.POST or None, request.FILES or None, user=request.user, instance=limiting)
    # ...

2. 建议的做法

  1. AbstractUser带有组和权限,您可以利用这些组和权限来检查您的用户是否属于某个或在执行操作之前具有某个权限(在这种情况下更新/批准表单),例如权限可以是:'fill_form_perm',' approve_form_perm',你的组可能是:'lead','officer'。

  2. 您可以将IntegerChoices用于模型中的排名,然后通过简单的比较来检查用户的权限级别。这更加灵活,因为您可以在多个级别中进行链接,例如在一种情况下低于经理但高于高级分析员,而不会带来太多麻烦。


推荐阅读