Not able to import views in djano, but it works in django shell
Question: I have the following simple urls.py:

    
    
    from django.conf.urls import patterns, include, url
    from base import views
    
    urlpatterns = patterns('',
        url(r'^test$', 'views.test', name='test'),
    )
    

And the following basic view: from django.shortcuts import render

    
    
    def test(request):
        return render(request, "base/test.html")
    

I have a project named blog and an app named base.

I know i can fix this by using "base.views.test" in the urls.py but in theory
this should be working i think because there is a **init**.py file in the base
directory.

When using views.test im getting "no module named views" as an error in django
but when i do this in the django shell it works:

    
    
     from base import views
     views.test
     function test
    

I'm wondering why this works in the django shell and not in django itself. No
matter what im doing in django, except from using the full absolute path to
the view im getting an error saying that i couldnt find a module named
views..so basically im looking for an explaination of why its not working, not
a solution since i know i could be using the full path to the view and make it
work.

Ive seen other threads on stackoverflow where a user has the same problem but
only a solution is provided, no explaination..they only tell people to use the
full path to the view but i dont really understand why it wouldnt work doing
it like that.. i know i also could be doing it this way:

    
    
    from django.conf.urls import patterns, include, url
    
    urlpatterns = patterns('base',
        url(r'^test$', 'views.test', name='test'),
    )
    

but im trying to understand why it isnt working when using "from base import
views" since it thought this would be working since its working with other
regular python modules.

File structure:

    
    
    .
    ├── base
    │   ├── __init__.py
    │   ├── __init__.pyc
    │   ├── models.py
    │   ├── static
    │   ├── templates
    │   │   └── base
    │   │       └── test.html
    │   ├── tests.py
    │   ├── views.py
    │   └── views.pyc
    ├── blog
    │   ├── __init__.py
    │   ├── __init__.pyc
    │   ├── settings.py
    │   ├── settings.pyc
    │   ├── urls.py
    │   ├── urls.pyc
    │   ├── wsgi.py
    │   └── wsgi.pyc
    └── manage.py
    

New traceback when adding (views.test without quotes, remove the old traceback
to avoid the post to get too long and unreadable):

    
    
    Environment:
    
    
    Request Method: GET
    Request URL: http://localhost:8000/test
    
    Django Version: 1.5
    Python Version: 2.7.7
    Installed Applications:
    ('django.contrib.auth',
     'django.contrib.contenttypes',
     'django.contrib.sessions',
     'django.contrib.sites',
     'django.contrib.messages',
     'django.contrib.staticfiles',
     'blog')
    Installed Middleware:
    ('django.middleware.common.CommonMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
     'django.middleware.csrf.CsrfViewMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware')
    
    
    Traceback:
    File "/Users/exceed/code/python/lib/python27/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
      92.                     response = middleware_method(request)
    File "/Users/exceed/code/python/lib/python27/lib/python2.7/site-packages/django/middleware/common.py" in process_request
      69.             if (not urlresolvers.is_valid_path(request.path_info, urlconf) and
    File "/Users/exceed/code/python/lib/python27/lib/python2.7/site-packages/django/core/urlresolvers.py" in is_valid_path
      551.         resolve(path, urlconf)
    File "/Users/exceed/code/python/lib/python27/lib/python2.7/site-packages/django/core/urlresolvers.py" in resolve
      440.     return get_resolver(urlconf).resolve(path)
    File "/Users/exceed/code/python/lib/python27/lib/python2.7/site-packages/django/core/urlresolvers.py" in resolve
      319.             for pattern in self.url_patterns:
    File "/Users/exceed/code/python/lib/python27/lib/python2.7/site-packages/django/core/urlresolvers.py" in url_patterns
      347.         patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
    File "/Users/exceed/code/python/lib/python27/lib/python2.7/site-packages/django/core/urlresolvers.py" in urlconf_module
      342.             self._urlconf_module = import_module(self.urlconf_name)
    File "/Users/exceed/code/python/lib/python27/lib/python2.7/site-packages/django/utils/importlib.py" in import_module
      35.     __import__(name)
    File "/Users/exceed/code/python/django/blog/blog/urls.py" in <module>
      8.     url(r'^test$', views.test, name='test'),
    
    Exception Type: NameError at /test
    Exception Value: name 'views' is not defined
    


Answer: Just pass your view function instead of string with dot path to it:

    
    
    from django.conf.urls import patterns, include, url
    
    from base import views
    
    urlpatterns = patterns('',
        url(r'^test$', views.test, name='test'),
    )
    

Quick explanation: you can pass into 2nd parameter of `url` either a function
or a string with dotted path to it. When it's a function, django will simply
call it when url is opened, when it's a dotted path: django will search for
that function in your `PYTHONPATH`. It doesn't matter if you import your
module inside your `urls.py`, django will always search in `PYTHONPATH`. You
can additionally pass prefix into first argument of patterns, and all
functions given by dotted path string will be searched relative to that
prefix.

So if you don't want to pass prefix into `patterns` (because for example you
are using multiple apps and only one `patterns`, the only solution here is to
pass functions instead of dotted paths. You can additionally use multiple
`patterns` (and specify different prefixes in each of them) and then include
them into main `patterns` (without prefix passed into it).

