Hi Andrea,

I answer below in between lines.

On 07 Oct 2014, at 08:53, Andrea <andrea.g...@gmail.com> wrote:

> Let's suppose I have a Foo app with a Bar model with a owner field. I want a 
> user to be able to edit all the instances for which obj.owner == request.user.
> 
> The model appears correctly in the admin panel for superusers and for users 
> for which I have explicitly assigned the permission change_bar or add_bar, as 
> explained here:
> 
> Assuming you have an application with an app_label foo and a model named Bar, 
> to test for basic permissions you should use:
> 
> add: user.has_perm('foo.add_bar')
> change: user.has_perm('foo.change_bar')
> delete: user.has_perm('foo.delete_bar')
> How can I show the model Bar in the admin index list without explicitly 
> assigning foo.change_bar or foo.add_bar to the user?
> 
> 

You can’t. The admin interface of Django assumes that when a user has access to 
the administrative interface of an App-Model it’s not to act as a mere passive 
consumer with read-only access but rather as an active admin over the content 
(add, change, delete). An administrator who does only inspect or supervise the 
content doesn’t fit in the sort of administrator that the Django administration 
app allows. It’s like allowing an administrator who actually does not 
administer. 

> So far I tried the following, expecting the Bar model to appear in the index 
> list page, but it didn't work.
> 
> class BarAdmin(admin.ModelAdmin):
>     def get_queryset(self, request):
>         qs = super(BarAdmin, self).get_queryset(request)
>         if request.user.is_superuser:
>             return qs        
>         return qs.filter(owner=request.user)
> 
>     def has_add_permission(self, request):
>         return True
> 
>     def has_change_permission(self, request, obj=None):
>         if obj is None:
>             return True
>         if obj.owner == request.user:
>             return True
>         return False
> 
>     def has_delete_permission(self, request, obj=None):
>         if obj is None:
>             return True
>         if obj.owner == request.user:
>             return True
>         return False
> 
>     def has_module_permission(self, request):
>         return True
> Accessing the link admin/foo/bar/ works correctly for every user and returns 
> the list of Bar instances for which obj.owner == request.user. 
> admin/foo/bar/add allows the user to add a new object correctly. These links 
> are although not displayed in the admin index page: which is the function 
> that triggers the appearance of the model in the index page? admin/foo/ 
> returns 403 Forbidden.
> 

Uhm… this looks strange to me. So you don’t want to provide the user with 
add/change/delete permissions but you are faking them. 

The Bar model doesn’t appear in the App index list page because the view 
function in charge first verifies whether the user has any of the 
add/change/delete permissions granted for such App, and given that your user 
doesn’t have them the App Foo is not listed. In other words, you would have to 
override the index admin view too (in django.contrib.admin.sites.py), which I 
don’t recommend. Think that by overriding the way permissions are handled in 
the admin interface you might end up giving change access to regular users that 
shouldn’t have access at all. 

My recommendation here is to create your own supervising interface for Foo, 
with its own URLs, to provide the readonly functionality your target users 
needs. Those users might not probably fall in the category of admins. I’m 
thinking in maybe managers who need to see what’s going on but doesn’t have to 
have write access.

Does this answer your questions?

> I'm using Django 1.7
> 
> Thanks,
> 
> Andrea
> 
> 

Cheers,
Daniel

Attachment: signature.asc
Description: Message signed with OpenPGP using GPGMail

Reply via email to