I tried to follow this tutorial https://blog.nicolasmesa.co/posts/2018/10/saas-like-isolation-in-django-rest-framework/
using: Django 3.1 Python 3.6
Everything I did including 'The User Messages App' paragraph worked perfectly right before the 'Refactoring the views' passage
and then I got the error when running manage.py runserver
django.core.exceptions.ImproperlyConfigured: The included URLconf 'saas_django.urls' does not appear to have any pa
tterns in it. If you see valid patterns in the file then the issue is probably caused by a circular import
I tried different types of import but I can't figure out where the cirular import happens
My steps to find a bug:
the saas_django/urls.py refers to user_messages app:
path('api/v1/user-messages/', include('user_messages.urls')),
user_messages/urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('', views.UserMessageList.as_view(),
name=views.UserMessageList.name),
path('<uuid:pk>', views.UserMessageDetail.as_view(),
name=views.UserMessageDetail.name),
]
It seems like something is wrong with the imported user_messages/views.py
from rest_framework import permissions
from rest_framework import generics
from . import serializers
from .models import UserMessage
class UserMessageList(generics.ListCreateAPIView):
name = 'usermessage-list'
permission_classes = (
permissions.IsAuthenticated,
)
serializer_class = serializers.UserMessageSerializer
queryset = UserMessage.objects.all()
def perform_create(self, serializer):
user = self.request.user
company_id = user.company_id
# Added from_user
serializer.save(company_id=company_id, from_user=user)
def get_queryset(self):
# Changed this to use the UserMessageManager's method
return UserMessage.objects.get_for_user(self.request.user)
class UserMessageDetail(generics.RetrieveAPIView):
name = 'usermessage-detail'
permission_classes = (
permissions.IsAuthenticated,
)
serializer_class = serializers.UserMessageSerializer
def get_queryset(self):
# Changed this to use the UserMessageManager's method
return UserMessage.objects.get_for_user(self.request.user)
I gues the cause of the error is something about these 2 lines:
from . import serializers
from .models import UserMessage
the user_messages/serializers.py also has the import of UserMessages
from rest_framework import permissions
from rest_framework import generics
from . import serializers
from .models import UserMessage
class UserMessageList(generics.ListCreateAPIView):
name = 'usermessage-list'
permission_classes = (
permissions.IsAuthenticated,
)
serializer_class = serializers.UserMessageSerializer
queryset = UserMessage.objects.all()
def perform_create(self, serializer):
user = self.request.user
company_id = user.company_id
# Added from_user
serializer.save(company_id=company_id, from_user=user)
def get_queryset(self):
# Changed this to use the UserMessageManager's method
return UserMessage.objects.get_for_user(self.request.user)
class UserMessageDetail(generics.RetrieveAPIView):
name = 'usermessage-detail'
permission_classes = (
permissions.IsAuthenticated,
)
serializer_class = serializers.UserMessageSerializer
def get_queryset(self):
# Changed this to use the UserMessageManager's method
return UserMessage.objects.get_for_user(self.request.user)
I tried to rewrite import as:
from .models import UserMessage as UM
but it didn't work.
Project structure is:
│ db.sqlite3
│ manage.py
│ sqlite3.exe
│
├───accounts
│ admin.py
│ apps.py
│ models.py
│ serializers.py
│ tests.py
│ urls.py
│ views.py
│ __init__.py
│
├───core
│ models.py
│ serializers.py
│ views.py
│ __init__.py
│
├───saas_django
│ asgi.py
│ settings.py
│ urls.py
│ wsgi.py
│ __init__.py
│
└───user_messages
│ admin.py
│ apps.py
│ models.py
│ serializers.py
│ tests.py
│ urls.py
│ views.py
│ __init__.py
│
├───migrations
My full code is here: https://github.com/SergSm/test-django-saas/
The question is how to properly debug this type of error?
First of all there are few issues in the project itself. There are unresolved references to serializers without which no one will be able to help out. For example:
This is referenced in a few other serializers. Also, other than this, there is one major issue in the way you have defined the models for:
The default method looks like this:
Not sure in what sequence you made these models but since you have not pushed your migrations onto the VCS, this will cause the issue.
Remember, always push your migrations on the VCS. I cannot highlight this enough. It can lead to serious issues as and when the project grows.
Else, on new setup, Django will never be able to identify correct dependency between models.
Coming to the other problem, since you have used default as method that gets ref from another model, Django will not allow me to make the migrations in the first place since the model itself that its referring to is not yet made.
This would have been solved if lets say you had 0001_initial one with the company model and the 0002_users where you refer the Company model. Also, you might want to look at the concept of fixtures that will help you populate a model on every fresh installation.
Coming to the main question you asked, if its indeed a circular, the best way is to closely inspect the traceback, it would show where the circular dep lies. Since I am unable to setup the project until the above mentioned issues are solved, I will not be able to give you a more directed answer.
Summary:
python manage.py makemigrationson the VCS, migrations are like commits of the state of your DB, you cannot expect to work with latest state without knowing the steps it was built from.migrate.That's all for now, if you fix the import issues, let me know. I'll be happy to take a look.
Cheers!