Open specialorange opened 4 years ago
Is 2.0.0 only partially ready for use or is there some upgrade step I might have missed?
More likely that it is ready but that I missed something with regard to upgrade.
I think what you've shared here is sufficient (thank you for the detail) to start investigating. I've used a precursor to the final 2.0.0 release for quite a while now, but it was not an upgrade from 1.x.
Actually I'll walk that back a bit @specialorange:
(I'm happy to show you if you'd like to see them).
If you want to share your models here or via email that'd make it easier for me!
Yes I would like it a lot. I plan on fixing some of the issues I think I can tackle in the coming weeks. You have helped me in the past, and I think I can finally contribute! :)
Current working v1
# admin.py
from organizations.base_admin import (BaseOwnerInline,
BaseOrganizationAdmin,
BaseOrganizationUserAdmin,
BaseOrganizationOwnerAdmin)
class OwnerInline(BaseOwnerInline):
model = AccountOwner
# raw_id_fields = ()
@admin.register(Account)
class AccountAdmin(BaseOrganizationAdmin):
list_display = ['slug', 'is_active', 'name', 'mgr', 'labor_rate',
'number_of_vendors', 'vendors_names', 'number_of_clients',
'clients_names', ]
inlines = [OwnerInline, ServiceInline]
inlines = [ServiceInline]
formfield_overrides = {models.ManyToManyField: {'widget': SelectMultiple(attrs={'size': '10'})}, }
@admin.register(AccountUser)
class AccountUserAdmin(BaseOrganizationUserAdmin):
list_display = ['user', 'organization', 'user_type', ]
# list_display = ['user_type', ]
# raw_id_fields = ()
@admin.register(AccountOwner)
class AccountOwnerAdmin(BaseOrganizationOwnerAdmin):
# raw_id_fields = ("organization_user", "organization")
list_display = ['organization', ]
# raw_id_fields = ()
# models.py
from organizations.abstract import (AbstractOrganization,
AbstractOrganizationUser,
AbstractOrganizationOwner)
class AccountUser(AbstractOrganizationUser):
user_type = models.CharField(max_length=1, default='', blank=True, null=True)
def __str__(self):
return str(self.user)
# class Meta(object):
# pass
class Account(AbstractOrganization):
mgr = models.ForeignKey(AccountUser, on_delete=models.DO_NOTHING, blank=True, null=True)
…
# Several unrelated methods
# def number_of_clients(self):
# return self.vendor_to.filter(vendor=self.pk).count()
class AccountOwner(AbstractOrganizationOwner):
# acct = models.ForeignKey(Account, on_delete=models.CASCADE, related_name='owner')
def __str__(self):
return str(self.organization_user)
# class Meta(object):
# pass
The v2 code is most of the commented out lines
+1 seems like the module registry thingy here not working properly. On my case the relationship not created.
CustomOrganization doesnt have attribute owner
I'm seeing the following when running makemigrations
3c3732bc1d26:/app$ ./manage.py makemigrations
SystemCheckError: System check identified some issues:
ERRORS:
core.User: (models.E012) 'unique_together' refers to the nonexistent field 'organization'.
core.User: (models.E012) 'unique_together' refers to the nonexistent field 'user'.
core.User: (models.E015) 'ordering' refers to the nonexistent field, related field, or lookup 'organization'.
core.User: (models.E015) 'ordering' refers to the nonexistent field, related field, or lookup 'user'.
Update: I was able to get around this issue by changing the order of classes in multiple inheritance.
class User(AbstractUser, AbstractOrganizationUser):
pass
@bennylope I was trying to upgrade to django-organizations 2.0 for the openwisp-users project but I'm having the same issue as seen above.
Do you have any suggestions on how to fix this? Errors below:
<class 'openwisp_users.admin.OrganizationOwnerAdmin'>: (admin.E002) The value of 'raw_id_fields[0]' refers to 'organization_user', which is not an attribute of 'openwisp_users.OrganizationOwner'.
<class 'openwisp_users.admin.OrganizationOwnerAdmin'>: (admin.E002) The value of 'raw_id_fields[1]' refers to 'organization', which is not an attribute of 'openwisp_users.OrganizationOwner'.
<class 'openwisp_users.admin.OrganizationOwnerAdmin'>: (admin.E108) The value of 'list_display[1]' refers to 'organization', which is not a callable, an attribute of 'OrganizationOwnerAdmin', or an attribute or method on 'openwisp_users.OrganizationOwner'.
<class 'openwisp_users.admin.OrganizationOwnerInline'>: (admin.E202) 'openwisp_users.OrganizationOwner' has no ForeignKey to 'openwisp_users.Organization'.
<class 'openwisp_users.admin.OrganizationUserAdmin'>: (admin.E002) The value of 'raw_id_fields[0]' refers to 'user', which is not an attribute of 'openwisp_users.OrganizationUser'.
<class 'openwisp_users.admin.OrganizationUserAdmin'>: (admin.E002) The value of 'raw_id_fields[1]' refers to 'organization', which is not an attribute of 'openwisp_users.OrganizationUser'.
<class 'openwisp_users.admin.OrganizationUserAdmin'>: (admin.E108) The value of 'list_display[0]' refers to 'user', which is not a callable, an attribute of 'OrganizationUserAdmin', or an attribute or method on 'openwisp_users.OrganizationUser'.
<class 'openwisp_users.admin.OrganizationUserAdmin'>: (admin.E108) The value of 'list_display[1]' refers to 'organization', which is not a callable, an attribute of 'OrganizationUserAdmin', or an attribute or method on 'openwisp_users.OrganizationUser'.
<class 'openwisp_users.admin.OrganizationUserInline'>: (admin.E202) 'openwisp_users.OrganizationUser' has no ForeignKey to 'openwisp_users.User'.
openwisp_users.OrganizationUser: (models.E012) 'unique_together' refers to the nonexistent field 'organization'.
openwisp_users.OrganizationUser: (models.E012) 'unique_together' refers to the nonexistent field 'user'.
openwisp_users.OrganizationUser: (models.E015) 'ordering' refers to the nonexistent field, related field, or lookup 'organization'.
openwisp_users.OrganizationUser: (models.E015) 'ordering' refers to the nonexistent field, related field, or lookup 'user'.
The short of the issue (or one of the issues) above is that in version 2.0 some of these field names/related names are dynamically named to be relevant to the underlying model. E.g. for a model named AccountUser
the field name is going to be account_user
now instead of organization_user
.
Going to have to think through how to either (a) make this more configurable or (b) create a smooth upgrade path.
@bennylope We experienced the same unique_together
warnings although we did not use a custom model name like @specialorange. However, after looking at organizations/models.py
we decided to also implement the OrganizationInvitation
class and poof! all errors were gone.
This is our working model config, if anyone interested:
class Organization(AbstractOrganization):
class Meta(AbstractOrganization.Meta):
abstract = False
class OrganizationUser(AbstractOrganizationUser):
# only allow one org per user
user = models.ForeignKey(
User, related_name="%(app_label)s_%(class)s", on_delete=models.CASCADE, unique=True
)
class Meta(AbstractOrganizationUser.Meta):
abstract = False
class OrganizationOwner(AbstractOrganizationOwner):
class Meta(AbstractOrganizationOwner.Meta):
abstract = False
class OrganizationInvitation(AbstractOrganizationInvitation):
class Meta(AbstractOrganizationInvitation.Meta):
abstract = False
Same here, I'm using custom models based on abstract classes and after upgrading to 2.0.0 I started seeing errors mentioning missing foreignkeys on the OrgOwner or OrgUser models.
Adding a concrete model for invitations (based on AbstractOrganizationInvitation) solved it as suggested by @eelkevdbos (thanks!)
Encountered the same problem. After a bit of digging into the source, the problem is line 104 in base.py
, the one goes if all([cls.module_...]):
if key:
cls.module_registry[module][key] = model
if all([cls.module_registry[module][klass] for klass in base_classes]):
model.update_org(module)
model.update_org_users(module)
which requires that all the abstract models to be overridden if model customization is required. That is, AbstractOrganization
, AbstractOrganizationUser
, AbstractOrganizationOwner
& AbstractOrganizationInvitation
. Only then would the dynamic field name injection mechanism would work. In my case I was not overriding the AbstractOrganizationInvitation
initially.
The sample code in the docs here omits the AbstractOrganizationInvitation
model.
I updated all pip packages ( https://stackoverflow.com/questions/2720014/how-to-upgrade-all-python-packages-with-pip [oops] ) which uses this package, and I've run into problems. Everything was working on v 1.1.1, and I am now getting some weird errors:
Notes
From what I can tell, and based on it working in 1.1.1, my models are set up correctly (I'm happy to show you if you'd like to see them). Is 2.0.0 only partially ready for use or is there some upgrade step I might have missed?