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 :)
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.
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