Getting 'str' object has no attribute 'objects' when using Model reference from setings.py

Hi there,

I have many Models, from which one is Workspace. I made a reference to this Model in settings.py to use it in otherfile.py, like below:

#settings.py

WORKSPACE_MODEL = "accounts.Workspace"

Now, when I try to use it in otherfile.py like below:

#otherfile.py

from django.conf import settings

Workspace = settings.WORKSPACE_MODEL

print(Workspace.objects.all())

I get below error:

'str' object has no attribute 'objects'

Error Full TraceBack is below:

Traceback Switch to copy-and-paste view
/app/.heroku/python/lib/python3.10/site-packages/django/core/handlers/exception.py, line 55, in inner
                response = get_response(request) …
Local vars
/app/.heroku/python/lib/python3.10/site-packages/django/core/handlers/base.py, line 197, in _get_response
                response = wrapped_callback(request, *callback_args, **callback_kwargs) …
Local vars
/app/.heroku/python/lib/python3.10/site-packages/django/views/generic/base.py, line 84, in view
            return self.dispatch(request, *args, **kwargs) …
Local vars
/app/.heroku/python/lib/python3.10/site-packages/django/contrib/auth/mixins.py, line 73, in dispatch
        return super().dispatch(request, *args, **kwargs) …
Local vars
/app/.heroku/python/lib/python3.10/site-packages/django/views/generic/base.py, line 119, in dispatch
        return handler(request, *args, **kwargs) …
Local vars
/app/apps/accounts/views.py, line 279, in post
        status_message = Workspace.objects.invite_workspace_user( …
Local vars
/app/apps/accounts/managers.py, line 118, in invite_workspace_user
        return Invitation.objects.send_invite_user_email(invitation, is_workspace_admin = make_admin) …
Local vars

I know some people will suggest me to import the model instead of using it’s reference like below:

from myapp.models import Workspace

print(Workspace.objects.all()

But, the issue is, I am importing classes from this otherfile.py to models.py as well. So let’s say I have to use the Workspace Model in TestClass in otherfile.py, then I am also importing this TestClass in models.py and if I directly import Workspace Model in otherfile.py, I get error of cyclic import from django, which is reasonable and fine for me, that’s why I want to use Workspace Model’s reference I created in settings.py.

Any help would be appreciated

Having a circular class dependency creates what we consider to be a “bad code smell”. In that situation, we generally try to examine our class and file structure to remove the circular dependency.

But you do have a couple choices to bypass the problem without refactoring.

To avoid the circular import issue, you can put the import statement inside the function in which it is needed. That defers the import until the function in which it is being used is executed.

You can also use the importlib.import_module function to do the import if you really need it to be variable at that point. (Something that could dynamically change)

@KenWhitesell can’t I use the approach which I was trying to use? For some reason I can’t see the definitions of functions and classes in the source code of my django. Can you copy-paste the source code of get_user_model() function. I want to see it’s source code, because it uses the Model reference from settings.py to get the User Model, so I will apply the same technique to get my models in otherfile.py

You’ve got it in your Django installation.
(It uses the import_module function.)

@KenWhitesell my issue is same as the issue explained here at stackoverflow python - Where should django manager code live? - Stack Overflow

I need to import my model in managers.py and also import managers in models.py. Can you have a look at the question and suggest me? Because there are a lot of solutions told in the stackoverflow discussion, but I don’t know which one is most efficient and which one leads to have low coupling in the code and high cohesion.

Our managers always reside in the models.py file. I find no reason or purpose to put them anywhere else. They are, fundamentally, part of the model. (The model code works with individual instances, while the managers are concerned with the collections of instances - queryset.)

Yeah, I have QuerySets for Managers and I am using those Managers in my Models. The problem here is that, my models.py is becoming too large, if I remember it correctly, its more than 1100 lines of code (but 1000+ lines are confirmed). So, how can I handle it easily if I place all the Managers and QuerySets in the same file with models? One thing I want to note here is that, I am documenting each class and function too, and this is making the models.py file even more larger.

That’s not even close to what we consider to be “too large”. (We start looking to refactor once files exceed 2500 lines.)

But, you do have another option.

You could structure your models as a Python module, with parts separated into individual files an then all imported within the module-level __init__.py file. (We’ve never bothered going in that direction, but I know it can be done.)

@KenWhitesell Can you give me an example of what you just said like structuring models as Python module with parts separated etc.?

The documentation is here: 6. Modules — Python 3.10.6 documentation

As I mentioned above - I know this can be done, but I’ve never done this in the context of a Django application.

Let me apply and I will let know about the results here.

@KenWhitesell I ended up having managers in the models.py.