【问题标题】:Create a form to activate user permission创建表单以激活用户权限
【发布时间】:2019-01-03 21:18:57
【问题描述】:

我想要一个 django 表单,它是 User 的一个实例,并获得一个由单选按钮构成的 html 表单来激活或停用权限。

这样的html代码应该在最后:

<div class="form-group">
    <label for="change_user">Can edit user:</label>
    <div class="labeled" id="change_user">
        <input class="with-gap" name="change_user_False" type="radio" id="change_user_False" value="False">
        <label for="change_user_False">No</label>
        <input class="with-gap" name="change_user_True" type="radio" id="change_user_True" value="True" checked="">
        <label for="change_user_True">Yes</label>
    </div>
</div>

这里的示例权限将是“change_user”,目标是以干净的 django 形式处理所有进程。我不知道什么是最合适的方式......

在一个简单的表单上使用并通过传入一个用户对象的参数来管理 clean 函数中的所有内容。

from django import forms

class PermissionForm(forms.Form):
    change_user = forms.ChoiceField(widget=forms.RadioSelect, choices=((True, 'No'), (False, 'Yes')), required=True)

     def __init__(self, *args, **kwargs):
          self.fields['change_user'].initial = select_user.has_permission('auth.change_user ')

     def clean(self, select_user):
         if self.cleaned_data['change_user']:
              select_user.permissions.add('change_user')

或者使用用户实例的一种形式:

from django.contrib.auth.models import User
from django import forms

class ProfileForm(forms.ModelForm):
    class Meta:
        model = User
        fields = []
        widget = ...

但是如何在radioselect中根据权限生成小部件并在返回数据错误时捕获错误?

【问题讨论】:

    标签: python django django-forms


    【解决方案1】:

    您可以使用 Django UpdateViewModelForm 解决您的问题,就像这个例子一样(请参阅 cmets 以了解发生了什么):

    forms.py:

    from django import forms
    from YOUR_APP_NAME import models
    
    class UserPermissionsForm(forms.ModelForm):
        change_user = forms.ChoiceField(
            widget=forms.RadioSelect,
            choices=[(True, 'Yes'), (False, 'no')],
            required=True  # It's required ?
        )
    
        class Meta:
            model = models.YOUR_MODEL_NAME
            fields = ('change_user',)  # I'll use only one field
    

    views.py:

    from django.views.generic import UpdateView
    from django.urls import reverse_lazy
    from django.contrib import messages
    from django.contrib.auth.models import Permission 
    from YOUR_APP_NAME import models, forms
    
    
    class UserPermissionView(UpdateView):
        model = models.YOUR_MODEL_NAME
        template_name = 'user_permission.html' # Your template name
        form_class = forms.UserPermissionsForm
        initial = {}  # We'll update the form's fields by their initial values
    
        def get_initial(self):
            """Update the form_class's fields by their initials"""
    
            base_initial = super().get_initial()
            # Here we'll check if the user has the permission of 'change_user'
            user_has_permission = self.request.user.user_permissions.filter(
                codename='change_user'
            ).first()
            base_initial['change_user'] = True if user_has_permission else False
            return base_initial
    
        def form_valid(self, form):
            """
            Here we'll update the user's permission based on the form choice:
            If we choose: Yes => Add 'change_user' permission to the user
                          No => Remove 'change_user' permission from the user
            """
            change_user = form.cleaned_data['change_user']
            permission = Permission.objects.get(codename='change_user')
            if change_user == 'True':
                self.request.user.user_permissions.add(permission)
                # Use django's messaging framework
                # We'll render the results into the template later
                messages.success(
                    self.request,
                    'Updated: User [{}] Can change user'.format(self.request.user.username)
                )
            else:
                self.request.user.user_permissions.remove(permission)
                messages.success(
                    self.request,
                    'Updated: User [{}] Cannot change user'.format(self.request.user.username)
                )
            return super().form_valid(form)
    
        def get_success_url(self):
            """
               Don't forget to add your success URL,
               basically use the same url's name as this class view
            """
            # Note here, we'll access to the URL based on the user pk number
            return reverse_lazy('user_permissions', kwargs={'pk': self.request.user.pk})
    

    urls.py:

    from django.urls import path
    from YOUR_APP_NAME import views
    
    
    urlpatterns = [
        path(
               'client/<int:pk>/',  # Access the view by adding the User pk number
               views.UserPermissionView.as_view(), 
               name='user_permissions'
        ),
        ... # The rest of your paths
    ]
    

    最后是模板:

    user_permissions.html:

    {% if messages %}
        {% for message in messages %}
            {{ message }}
        {% endfor %}
        <br><br>
    {% endif %}
    
    <div>User: {{ user.username }}</div>
    <form method="POST">
        {% csrf_token %}
        {{ form.as_p }}
        <button type='submit'>Submit</button>
    </form>
    

    以下是此解决方案流程的一些屏幕截图:

    当然,您可以在 Django 管理面板下检查权限的添加/删除操作。

    【讨论】:

    • 这非常接近我想要做的事情。但是当我使用fields = ('change_user',)(像你一样)时,我得到了休闲错误django.core.exceptions.FieldError: Unknown field(s) (change_user) specified for User,因为User没有直接的change_user值......当我尝试ModelForm方式时,这是我的问题。
    • 试试__all__,然后告诉我是直接使用django的User模型还是使用外键/OneToOneFieldUser模型?
    • 我直接使用模型Django User模型。我可以将任何权限称为真正的 OneToMany 关系(由 django 框架定义的权限)以在它们上应用小部件......并且使用字段和小部件创建 ModelForm 是没有意义的。我想我需要在Form 中处理所有过程(有点像你做的)。
    猜你喜欢
    • 1970-01-01
    • 2019-04-25
    • 1970-01-01
    • 1970-01-01
    • 2016-12-14
    • 1970-01-01
    • 2012-09-27
    • 2017-11-11
    • 1970-01-01
    相关资源
    最近更新 更多