Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Admin page: model instance is None #55

Closed
David-OConnor opened this issue May 15, 2017 · 8 comments
Closed

Admin page: model instance is None #55

David-OConnor opened this issue May 15, 2017 · 8 comments

Comments

@David-OConnor
Copy link

David-OConnor commented May 15, 2017

I've gotten the Django permission tests to work as per the docs, but when attempting admin integration, I'm unable to get the model instance to be accepted by the predicate. The user is passed appropriately, but the model instance (book) in the example) is always None. I'm following the tutorials exactly, and am on Django 1.11. What could cause this?

@rules.predicate
def in_section(user, person_instance):
    #This always produces an exception, because person_instance is always None.
    return user.person.section == person_instance.section

rules.add_perm('myapp', rules.always_allow)
rules.add_perm('myapp.add_person', in_section) 
@dfunckt
Copy link
Owner

dfunckt commented May 19, 2017

You probably missed to subclass ObjectPermissionsModelAdmin: https://github.com/dfunckt/django-rules#rules-and-permissions-in-the-admin

@David-OConnor
Copy link
Author

Unfortunately, that's not it.

@dfunckt
Copy link
Owner

dfunckt commented May 20, 2017

Hmm, have you configured AUTHENTICATION_BACKENDS as per https://github.com/dfunckt/django-rules#checking-for-permission? Also, is your PersonModelAdmin subclassing several classes besides ObjectPermissionsModelAdmin by any chance?

@dfunckt
Copy link
Owner

dfunckt commented May 20, 2017

Oh wait, I just realised you're trying to access the created instance when adding an instance via the admin. This won't work, and is expected -- the Person instance hasn't even been created at the time Django asks for permission -- i.e. myapp.add_person.

@dfunckt
Copy link
Owner

dfunckt commented May 20, 2017

Apparently you're confusing the semantics of the add permission, probably interpreting it as "is this user allowed to save this Person instance?", while it's actually more like "is this user allowed to add a Person instance?".

See here: https://github.com/django/django/blob/master/django/contrib/admin/options.py#L433-L440

@David-OConnor
Copy link
Author

David-OConnor commented May 20, 2017

Thank you for the detailed replies. Yep, I configured AUTHENTICATION_BACKENDS per that guide. It seems like I've misunderstood how this library works regarding the Admin page. Is it correct that there's no easy way to restrict admin permissions based on simple rules?

I was able to get a 90% solution by editing classes in admin.py to look like this: (Users who have model-level permission could access rows outside their section by entering a specific URL, but this at least hides things)

@admin.register(Person)
class PersonAdmin(ModelAdmin):
     # Normal admin.py boilerplate goes here

    def get_queryset(self, request):
        """Only show people in the user's section."""
        qs = super(PersonAdmin, self).get_queryset(request)
        if request.user.is_superuser:
            return qs.all()
        else:
            return qs.filter(squadron=request.user.person.section)

    def render_change_form(self, request, context, *args, **kwargs):
        """ Only allow the user's section when adding/changing a person."""
        if not request.user.is_superuser:
            context['adminform'].form.fields['section'].queryset = Squadron.objects.filter(
               number=request.user.person.squadron.number)
        return super(PersonAdmin, self).render_change_form(request, context, args, kwargs)

@dfunckt
Copy link
Owner

dfunckt commented May 20, 2017

It seems like I've misunderstood how this library works regarding the Admin page. Is it correct that there's no easy way to restrict admin permissions based on simple rules?

No, this is not correct, you can restrict permissions based on rules -- that's what django-rules is all about. You have misunderstood how Django permissions work. Please take another look on this project's README and the relevant section in Django docs about authorisation.

Closing -- please reopen if there are rules-related questions I may answer.

@dfunckt dfunckt closed this as completed May 20, 2017
@jlugao
Copy link

jlugao commented Sep 11, 2018

Hey, I am sorry to bring up this old issue, but I didn't want to open a new one just to ask a question. But I am kinda confused about this too. Is it possible to limit the list results in the admin list display just by using rules?

please let me know @dfunckt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants