bennylope / django-organizations

:couple: Multi-user accounts for Django projects
http://django-organizations.readthedocs.org/
BSD 2-Clause "Simplified" License
1.3k stars 212 forks source link

Manager isn't accessible via Account instances #162

Closed specialorange closed 6 years ago

specialorange commented 6 years ago

I have tried my best, but some concepts seem to be evading me. I appreciate your work and help. Thanks!

Related issues?

I am not sure, but from what I am reading in the source, this seems related to #161 and #154 .

Stack Overflow

https://stackoverflow.com/questions/52526388/manager-isnt-accessible-via-account-instances

In using django-organizations to give my project organizations, I made a separate app for accounts.

Using the code from the docs (https://django-organizations.readthedocs.io/en/latest/cookbook.html#advanced-customization-using-abstract-models) in what I assume is a basic case, I am trying to add them on

the admin.py page:

from accounts import models as AccountModels

@admin.register(AccountModels.Account)
class AccountAdmin(admin.ModelAdmin):
    list_display = ['slug', 'active', ]

This gives an error when trying to view the list on admin page for Accounts (at http://localhost:8000/adminaccounts/account/) [ps - the add page renders, but will provide the same error on save]:

AttributeError at /adminaccounts/account/

Manager isn't accessible via Account instances

Looking at the error, I am not supposed to be calling it on an instance, rather only a Class. But the default admin template is rendering this page, so I am wary of editing that. Is there something I am missing related to setting up an inherited class in an admin class? (the organization-user and organization-owner both display properly adding to my confusion)

This is the stack that shows that it is trying to access an instance (but I can't find in the stack trace which line is the producing the error, only that it is in the {{content}} part of the template block):

/Users/me/.virtualenvs/myFirst/lib/python3.6/site-packages/django/contrib/admin/utils.py in lookup_field
            attr = getattr(obj, name) ...
▼ Local vars
Variable      Value
model_admin   <accounts.admin.AccountAdmin object at 0x11e0185f8>
name          'active'
obj           <Account: Funny Clowns With Paper Boats>
opts          <Options for Account>

/Users/me/.virtualenvs/myFirst/lib/python3.6/site-packages/django/db/models/manager.py in __get__
            raise AttributeError("Manager isn't accessible via %s instances" % cls.__name__) ...
▼ Local vars
Variable      Value
cls           <class 'accounts.models.Account'>
instance      <Account: Funny Clowns With Paper Boats>
self          <django.db.models.manager.ManagerDescriptor object at 0x11dabb978>

The accounts models.py (just the same as the docs):

from django.db import models
from organizations.abstract import (AbstractOrganization,
                                    AbstractOrganizationUser,
                                    AbstractOrganizationOwner)

class Account(AbstractOrganization):
    monthly_subscription = models.IntegerField(default=1000)

class AccountUser(AbstractOrganizationUser):
    user_type = models.CharField(max_length=1, default='')

class AccountOwner(AbstractOrganizationOwner):
    pass

I do not have any functional views or Class based views in the accounts app, so I don't know if I am supposed to override a manager or search query or view...

Trying to override the view(?) of the admin :

@admin.register(Account)
class AccountAdmin(BaseOrganizationAdmin):
    def get_queryset(self, request):
        qs = super(AccountAdmin, self).get_queryset(request)
        print(Account)         # <class 'accounts.models.Account'>
        print(type(Account))   # <class 'organizations.base.OrgMeta'>
        print(type(qs))        # <class 'django.db.models.query.QuerySet'>
        return qs # or Account

This either produces the previous error, or type object 'Account' has no attribute 'filter'

bennylope commented 6 years ago
from accounts import models as AccountModels

@admin.register(AccountModels.Account)
class AccountAdmin(admin.ModelAdmin):
    list_display = ['slug', 'active', ]

active in the list display refers to the ActiveManager instance, what you want here is the is_active field name I think.