Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I get 'ImproperlyConfigured' exception, implying circular imports?

Tags:

django

I have had this issue before, but I've managed to find the circular import being referenced. I face it again, but I can't find the problem.

My project's name is 'sare', and my sare/urls.py looks like this:

from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path('users/', include('users.urls', namespace='users')),
    path('admin/', admin.site.urls),
]

And users/urls.py is this:

from django.urls import path
from .views import UsersTableView#, UserCreateView, UserUpdateView, UserDeleteView

app_name = 'users'

urlpatterns = [
    path('table/', UsersTableView.as_view(), name='users_table'),
    # path('create/', UserCreateView.as_view(), name='users_create'),
    # path('update/<int:pk>', UserUpdateView.as_view(), name='users_update'),
    # path('delete/<int:pk>', UserDeleteView.as_view(), name='users_delete'),
]

The only piece of code that is not commented in my views is the UsersTableView, that looks like this:

from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from .models import CustomUser
from .tables import UsersTable
from .filters import UserFilter
from .form_helpers import UsersFilterFormHelper
from django.views.generic import CreateView, UpdateView, DeleteView
from .forms import UserForm
from django.urls import reverse_lazy, reverse
from django_tables2.export import ExportMixin
from django_tables2 import RequestConfig,SingleTableView,Table as TableBase
from django_filters import FilterSet


class InitUserMixin(object):
    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop("user", None)
        super(InitUserMixin, self).__init__(*args, **kwargs)


class FilterUserMixin(InitUserMixin, FilterSet):
    pass


class Table(InitUserMixin, TableBase):
    pass


class PagedFilteredTableView(ExportMixin, SingleTableView):
    filter_class = None
    formhelper_class = None
    context_filter_name = 'filter'

    def get_queryset(self, **kwargs):
        qs = super(PagedFilteredTableView, self).get_queryset()
        self.filter = self.filter_class(self.request.GET, queryset=qs, user=self.request.user)
        self.filter.form.helper = self.formhelper_class()
        return self.filter.qs

    def get_table(self, **kwargs):
        table = super(PagedFilteredTableView, self).get_table(user=self.request.user)
        RequestConfig(self.request, paginate={'page': self.kwargs.get('page', 1),
                                              "per_page": self.paginate_by}).configure(table)
        return table

    def get_context_data(self, **kwargs):
        context = super(PagedFilteredTableView, self).get_context_data(**kwargs)
        context[self.context_filter_name] = self.filter
        return context


class UsersTableView(LoginRequiredMixin,PagedFilteredTableView, UserPassesTestMixin):
    model = CustomUser
    table_class = UsersTable
    template_name = 'users/users_table.html'
    paginate_by = 10
    filter_class = UserFilter
    formhelper_class = UsersFilterFormHelper

    def test_func(self):
        if self.request.user.is_superuser:
            return True
        else:
            return False

I've tried to comment everything in the view and just write pass, but it gives the same result. I cannot see any circular import. Do you see anything wrong with this code, or something else I should check out?

Traceback (most recent call last):
  File "C:\Users\Iván\AppData\Local\Programs\Python\Python36\Lib\threading.py", line 916, in _bootstrap_inner
    self.run()
  File "C:\Users\Iván\AppData\Local\Programs\Python\Python36\Lib\threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\Iván\AppData\Local\Programs\Python\Python36\Lib\site-packages\django\utils\autoreload.py", line 53, in wrapper
    fn(*args, **kwargs)
  File "C:\Users\Iván\AppData\Local\Programs\Python\Python36\Lib\site-packages\django\core\management\commands\runserver.py", line 117, in inner_run
    self.check(display_num_errors=True)
  File "C:\Users\Iván\AppData\Local\Programs\Python\Python36\Lib\site-packages\django\core\management\base.py", line 395, in check
    include_deployment_checks=include_deployment_checks,
  File "C:\Users\Iván\AppData\Local\Programs\Python\Python36\Lib\site-packages\django\core\management\base.py", line 382, in _run_checks
    return checks.run_checks(**kwargs)
  File "C:\Users\Iván\AppData\Local\Programs\Python\Python36\Lib\site-packages\django\core\checks\registry.py", line 72, in run_checks
    new_errors = check(app_configs=app_configs)
  File "C:\Users\Iván\AppData\Local\Programs\Python\Python36\Lib\site-packages\django\core\checks\urls.py", line 13, in check_url_config
    return check_resolver(resolver)
  File "C:\Users\Iván\AppData\Local\Programs\Python\Python36\Lib\site-packages\django\core\checks\urls.py", line 23, in check_resolver
    return check_method()
  File "C:\Users\Iván\AppData\Local\Programs\Python\Python36\Lib\site-packages\django\urls\resolvers.py", line 406, in check
    for pattern in self.url_patterns:
  File "C:\Users\Iván\AppData\Local\Programs\Python\Python36\Lib\site-packages\django\utils\functional.py", line 48, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "C:\Users\Iván\AppData\Local\Programs\Python\Python36\Lib\site-packages\django\urls\resolvers.py", line 596, in url_patterns
    raise ImproperlyConfigured(msg.format(name=self.urlconf_name))
django.core.exceptions.ImproperlyConfigured: The included URLconf 'sare.urls' does not appear to have any patterns in it. If you see valid patterns in the file then the issue is probably caused by a circular import.

EDIT:

My settings.py is this:

import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '^*5r6l%i-dubv_ur*p06d*rp@d@*dg@4z%&li8#f4ca=h9z-r*'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'rest_framework',
    'rest_framework.authtoken',
    'sare',
    'formats',
    'users',
    'crequest',
    'django_tables2',
    'django_filters',

    #'allauth',  # registration
    #'allauth.account',  # registration
    #'allauth.socialaccount',  # registration
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'sare.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'sare.wsgi.application'


# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}


# Password validation
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/3.0/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/

STATIC_URL = '/static/'

AUTH_USER_MODEL = 'users.CustomUser'
like image 365
Iván Flores Vázquez Avatar asked Apr 30 '20 01:04

Iván Flores Vázquez


2 Answers

Watch out for the MRO (method resolution order) in your view class UsersTableView(LoginRequiredMixin, PagedFilteredTableView, UserPassesTestMixin), the mixins should always be at the beginning of hierarchy to be taken into account.

Otherwise, to see what would be the circular import, we would need the content of the following files:

  • models.py
  • tables.py
  • filters.py
  • form_helpers.py
  • forms.py

Or you can try to debug it yourself:

  1. simply launch a python interpreter in your project
  2. import sare.urls or import sare.views
  3. it should give a ImportError, a more precise clue as to where the circular import is
like image 125
SebCorbin Avatar answered Oct 19 '22 06:10

SebCorbin


Are you importing UsersTableView properly and defined it? it seems your use case is pretty beginner level of Django so I suggest check the Django class-based views and URLs docs again and check your code accordingly.

like image 31
auvipy Avatar answered Oct 19 '22 06:10

auvipy