Victor Aragon
Victor Aragon

Reputation: 13

Is there a way to make data visible per user in wagtail modeladmin?

I'm adding a family tree manager in wagtail admin ModelAdmin, the structure is something like this:

Clients/
    Management
    Family Tree/
        Person/

So I need to make sure that every family tree and Person (members of the family tree) are available just to the user that input the data (and the admin).

It's my first time with wagtail, I just read the docs but any advice is welcome :)

Upvotes: 1

Views: 916

Answers (1)

Loïc Teixeira
Loïc Teixeira

Reputation: 1434

Filtering on the model admin view

On your ModelAdmin class, you should define get_queryset to filter the items shown on the list view as per your need.

However it would only not display the items, a user would still be able to access other items by modifying the URL. To prevent that, you'll want to define a permission_helper_class and set the user_can_inspect, user_can_create, user_can_edit and user_can_delete methods to return True/False accordingly.

Assigning the user to the created object

Based on your comment below, let's assume you have the following model definition:

from django.conf import settings
from django.db import models

class FamilyTree(models.Model):
    managed_by = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=False)
    # Some other fields.

Note that null=False will fail if you already have some entries in the database. If that's the case, you'll have to create some custom migrations.

In order to assign the user creating an object with the object itself, you'll have to override the CreateView of the model admin with a custom one.

from django.forms.widgets import HiddenInput
from wagtail.contrib.modeladmin.views import CreateView

class FamilyTreeCreateView(CreateView):
    def get_form(self):
        form = super().get_form()
        form.fields['managed_by'].widget = HiddenInput()
        return form

    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs['data']['managed_by'] = self.request.user  # Add the data so the form validates properly.
        return kwargs

Note that this way, it will output a hidden managed_by form field which you later set to the correct value. If that's an issue for you, you would have to exclude the field and then overwrite the form_valid method. I chose not to because you would have to overwrite the method completely (and experience shows that a given update of Wagtail will differ from your copied implementation and you won't notice), not just override/extend it as the initial method calls form.save() which would fail as the required managed_by field is missing.

And then set this view on your model admin:

from wagtail.contrib.modeladmin.options import ModelAdmin
from myviews import FamilyTreeCreateView

class FamilyTreeAdmin(ModelAdmin):
    create_view_class = FamilyTreeCreateView

Upvotes: 2

Related Questions