Question

I am working with Django at the moment and its admin page. I have several classes with some attributes. I created a group where the users of this group have permissions to add, change and remove several content of the attributes of these classes. Now there is also some attributes in the classes, which are not of relevance for the the user of this group but for the SuperUser why I would not delete them in my models. I want to hide several fields to the user of this group because I can just set up to change, add and remove every attribute of a class and not several attributes of a class. Is it possible to do that and when yes, how ? help is much appreciated and if you got any questions please ask me.

Edit:

from django.contrib import admin
from programm.models import completedTask

class completedTasks(admin.ModelAdmin):
        fields = ["date", "duration"]
        def change_view(self, request, object_id, extra_context=None):
                restricted_groups = set(["Azubi"])
                extend_list = ["documentationReference", "educationDepartment"]
                if not set(request.user.groups.values_list("name", flat=True)).intersection(restricted_groups):
                        self.fields.extend(extend_list)
                return super(completedTasks, self).change_view(request, object_id, extra_context=extra_context)

admin.site.register(completedTask, completedTasks)
Was it helpful?

Solution

Following might work for you, but I did not test it.

Fieldsets must be a list. tuple and other un-editable types must not used since you will edit the contents of them on runtime. Add all fields to your fieldset, including the attributes you want to restrict for certain groups

restricted_groups = set() # you must either define this statically or fill it on runtime. But it must be a set

class QuestionAdmin(admin.ModelAdmin):
    fieldsets = [
        ('custom',           {'fields': ['question_text', 'item1', 'item2']}),
        ('Date information', {'fields': ['pub_date']}),
    ]

    def change_view(self, request, object_id, extra_context=None):
        if set(request.user.groups.values_list("name", flat=True)).intersection(restricted_groups):  # If there is same group(s) in both the users groups and the restricted groups, then user will not see following fields
            filter(lambda x: x[0]=="custom", self.fieldsets)[0][1]["fields"].remove("item1")
            filter(lambda x: x[0]=="custom", self.fieldsets)[0][1]["fields"].remove("item1")
        return super(QuestionAdmin, self).change_view(request, object_id, extra_context=extra_context)

you can use the same thing to add_view too. Here is the doc

Update, request.user group filtering fixed and set to use group name. If you wish to use another attribute (ex, group id) you must change it Note: That code is not tested, but I write it according to ones (slightly different ones). You better test it and check if it works fine for both restricted groups and unrestricted groups.

Update 2: It is clear that this is not the best way to go if you insist on using fieldsets because it is structure is not much suitable for that kind of approach. That example is based on that you give a unique name to each of your categories (in my example custom) and each fields attribute contains list of fields, not tuples for sub-categorizing it.

Following is another approach, based on adding those fields if the user in not in restricted_groups:

class completedTasks(admin.ModelAdmin):
    fieldsets =     [
            (None,  {'fields': ['date']}),
            (None,  {'fields': ['duration']}),
            (None,  {'fields': ['documentationReference']}),
            ("Extra", {'fields': []}),
                    ]

    def change_view(self, request, object_id, extra_context=None):
        if not set(request.user.groups.values_list("name", flat=True)).intersection(restricted_groups): # there is no restricted group in users groups
            filter(lambda x: x[0]=="Extra", self.fieldsets)[0][1]["fields"].extend(["field1", "field2"]) # add fields to fieldsets. extend must accept a list of fields to be added to the admin
        return super(completedTasks, self)..change_view(request, object_id, extra_context=extra_context)

Update: Sinmce you have only one group, u remove the usage of set. I used changelist_view in my porject for such proposes, I aso added it to the code

class completedTasks(admin.ModelAdmin):
    fields = ["date", "duration"]
    def change_view(self, request, object_id, extra_context=None):
        if "Azubi" not request.user.groups.values_list("name", flat=True):
            if "field1" not in self.fields:
                self.fields.append("field1")
        else:
            if "field1" in self.fields:
                self.fields.remove("field1")
        return super(completedTasks, self).change_view(request, object_id, extra_context=extra_context)

    def changelist_view(self, request, extra_context=None):
        if "Azubi" not request.user.groups.values_list("name", flat=True):
            if "field1" not in self.fields:
                self.fields.append("field1")
        else:
            if "field1" in self.fields:
                self.fields.remove("field1")
        return super(completedTasks, self).changelist_view(request, extra_context=None)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top