0

I want to build a custom view that gives ( or take depending on the situation) permission(s) to user. What I want to do is to produce a form with all the permissions listed with check boxes next to each permission, checked already against a permission given to user. In simpler words, I want to make the customised version of Django Admin where I can give or take back the permissions. How can I do this?

I can get a list of permissions by using

from django.contrib.auth.models import Permission
per=Permission.objects.all()

similarly I can get the user object by using user=User.objects.get(id=id) model. But how can I produce a form with which has check boxes and a view to connect all the checked/unchecked permissions to the user?

This is my views.py

class UserUpdate(UserPassesTestMixin, UpdateView):
    models = User
    fields = ('username', 'email', 'first_name', 'last_name', 'is_staff', 'is_active', 'is_superuser',
              'user_permissions')

    def get_object(self, queryset=None):
        obj = User.objects.get(pk=self.kwargs['pk'])
        self.success_url = reverse_lazy('admin:user_detail', kwargs={'pk': obj.pk})
        return obj

    def test_func(self):
        return self.request.user.is_superuser

{% extends 'admin_app/base.html' %}
{% load bootstrap4 %}
{% block content_class %}
    <form method="POST">
        {% csrf_token %}
        {% bootstrap_form form %}
        <input type="submit" value="Update">
    </form>
{% endblock %}

Template

I want the page to show all the given permissions to user+ add/remove them just like it is in the Admin Panel.

Deshwal
  • 3,436
  • 4
  • 35
  • 94
  • Use a `ModelMultipleChoiceField` in your `Form` with `Permission.objects.all()` as QuerySet and when the form is valid, assign the selected permissions to the user (`user.permissions.add(...)` or `user.permission.set(...)`) – dirkgroten Aug 12 '19 at 09:20
  • can you please post a dummy form, view and template for the same? @dirkgroten – Deshwal Aug 12 '19 at 09:23
  • no this is not a coding service. I've told you the basics and if you read the [Django docs](https://docs.djangoproject.com/en/2.2/topics/forms/) on how to work with forms, this should be quite easy. The docs show you how to build a Form, a view and a template, in your case these examples will work perfectly. – dirkgroten Aug 12 '19 at 09:25
  • No, SO is just not for asking others to write your code. It's for asking specific help when you're stuck with your code, after you show what you've tried and also show that you've done some research on the topic. See [ask] and how to write a [mcve]. – dirkgroten Aug 12 '19 at 09:48
  • The solution you provided, it throws the same thing what UserUpdateForm throws. a box full of fields. I just want to know how to update these values. – Deshwal Aug 12 '19 at 09:48
  • Set the `widget` of the field to `CheckboxSelectMultiple`. The default one is `SelectMultiple` which is the box where you can ctrl-click to select multiple. – dirkgroten Aug 12 '19 at 09:50
  • @dirkgroten my brother! see! listen. When you use UserUpdateForm, it'll show the same form. I want to know how would you select/deselect fields from it? In admin Interface, it shows a different panel to show what permissions you have. I am just trying to re create this one only. – Deshwal Aug 12 '19 at 09:51
  • CheckBoxSelectMultiple shows nothing. It shows a dropDown menu and an input field where you can just input the CODENAME – Deshwal Aug 12 '19 at 09:53
  • You're not showing your code. Add your view code and form code (I don't know what is `UserUpdateForm`, it's not a django standard form) and template code, show us your [mcve] and which issue you're facing. – dirkgroten Aug 12 '19 at 09:54
  • @dirkgroten Please take a look at the code and the edited part. Thanks in advance. – Deshwal Aug 12 '19 at 10:29
  • but you're not overriding the form, where did you try to add `ModelMultipleChoiceField`? Remove `fields` from your view and override the form by setting `form_class` to your form. – dirkgroten Aug 12 '19 at 10:34
  • The form from this view shows a list of all the permissions that we can provide to the user. Problem is that I can select them via using ctrl+click but not able to remove the permissions. I just want the 2 thing right now, to show verbose names of the permissions and a button to deselect them. Help me with this one – Deshwal Aug 12 '19 at 10:54

2 Answers2

0

I'm using crispy forms to generate fast and somewhat cool forms from a model. You can also use bootstrap4 for css. Its super quick and easy when you get the hang of it.

You can use any model and reference it in crispy form Layout something like this

self.helper.layout = Layout(
Fieldset('User',
         Div('username', 'first_name', 'last_name', 'email')),
Div(
    Div('is_staff', css_class="col-md-2"),
    Div('is_active', css_class="col-md-3"),

    css_class='row',
),

ButtonHolder(Submit('save', 'Save settings')),

ButtonHolder(Submit('delete', bot_button_label, css_class='btn-danger'), css_class="mt-3")
)
TreantBG
  • 1,192
  • 6
  • 25
  • 44
  • Thanks a lot bud..but it's not about the forms. It is about the form that gives permissions to the user. I know how to render a form. – Deshwal Aug 12 '19 at 09:44
  • you can also load the permissions associated with the user in this form. and have on save function to update them. i don't see how to do it without write some custom form. Sorry if i didn't help – TreantBG Aug 12 '19 at 10:19
  • No bud! your're good but thisis way too over my head. I'm just new to Django still learning. – Deshwal Aug 12 '19 at 10:30
0

Override the form (the Django UpdateView uses a modelform_factory to automatically generate the form).

In your view: - Remove fields variable. - Add form_class = MyUserUpdateForm

class UserUpdate(UserPassesTestMixin, UpdateView):
    model = User
    form_class = MyUserUpdateForm

    ...

Now create MyUserUpdateForm where you override the widget for user_permissions field. If your user_permissions field already contains the right choices you only need to override the widget, as described here:

class MyUserUpdateForm(forms.ModelForm):

    model = User
    fields = ('username', 'email', 'first_name', 'last_name', 'is_staff', 'is_active', 'is_superuser',
          'user_permissions')
    widgets = {'user_permissions': CheckboxSelectMultiple}

If you want to also override the queryset (the default is Permission.objects.all()) then you'd override the field itself entirely, as described at the bottom of the overriding default fields.

dirkgroten
  • 20,112
  • 2
  • 29
  • 42