My views.py got bloated, and I decided to cut it up into smaller modules by creating a ./views directory with all the little .py files. Here's what I get when I start the test webserver:
File "/path/to/the/app/views/__init__.py", line 1, in <module>
from my_view import my_view
ImportError: No module named 'my_view'
My ./views directory contains __init__.py, which is several lines of:
from my_view import my_view
from my_other_view import my_other_view
#etc...
./views/my_view.py of course looks like:
def my_view(request):
#etc...
I've obviously overlooked something, but I can't think what. Can you see the error I have made?
I guess views is not in your PYTHON_PATH. Which is right. However this means you should use relative python imports:
from .my_view import my_view # note the leading dot
Or absolute import from your project root (which should be in your PYTHON_PATH):
from myapp.views.my_view import my_view
Related
I am working on a Django project. I am working on the register page. When I try to import my register/views.py to my mysite/urls.py file I get an error message. ModuleNotFoundError: No Module named 'register'. Both files are are in the same directory.
from django.contrib import admin
from django.urls import path, include
from register import views as v
Adding full exception message
Try the following:-
from . import views
Please add a blank __init__.py file in the register folder.
Only then python will understand that register is an importable package
Edit:
After seeing the exception, it looks like a working directory issue in pycharms. Please try the fix mentioned in this link
File "C:\Users\user\app-rest\app\app\urls.py", line 4, in <module>
from app.myapp.views import UserViewSet
ModuleNotFoundError: No module named 'app.myapp'
Not sure what the issue is but when I comment out the import and the related views on my URL page, it works. Could it be from the folder being app\app\url being the same name twice? if it is how can I change that without screwing up the rest of my code?
settings are set up right because it usually works.
Thank everyone in advance.
This looks like a good use case for a relative import, if you are accessing the view from within the same django app, then replace the import statement with
from .views import UserViewSet
Reference
I ran into the following ModuleNotFoundError error.
File "C:\django-project\CodingWithMitchBlog\demoproject\Blog\api\urls.py", line 3, in <module>
from demoproject.Blog.api.views import api_detail_BlogPost_view
ModuleNotFoundError: No module named 'demoproject.Blog'
'Blog' is my appname.
This is my project structure.
This might be due to incorrect import statements used in the files. If the import statements has the projectname prefixed try removing it and run again.
For example change:
from demoproject.Blog.models import ModelClass
to
from Blog.models import ModelClass
in the urls.py file
Why do both of the following ways of importing UpdateView work?:
1. from django.views.generic import UpdateView
2. from django.views.generic.edit import UpdateView
I was assuming 2. was the correct way, and 1. would not work, but from testing both work.
What you see here is quite common (at least in some Python packages). If you define a .py file, that acts as a module. For example the django.views.generic.edit module maps on the django/views/generic/edit.py file [GitHub].
A directory is a Python module as well (due to the __init__.py file), but it does not contain any elements by default, hence that would mean that django.views.generic would be empty.
If we take a look at the django/views/generic/__init__.py file [GitHub], we see:
from django.views.generic.base import RedirectView, TemplateView, View
# ...
from django.views.generic.edit import (
CreateView, DeleteView, FormView, UpdateView,
)
# ...
__all__ = [
'View', 'TemplateView', 'RedirectView', 'ArchiveIndexView',
'YearArchiveView', 'MonthArchiveView', 'WeekArchiveView', 'DayArchiveView',
'TodayArchiveView', 'DateDetailView', 'DetailView', 'FormView',
'CreateView', 'UpdateView', 'DeleteView', 'ListView', 'GenericViewError',
]
# ...
This thus imports the UpdateView from the generic.py file, and re-exports the class.
You thus can reference to the class in two ways: through the module defined by the generic.py file, or through the re-export of the module of the directory, specified through the __init__.py file.
This is typically done to export a portion of the items that are defined in the files, export these under a more convenient name, or provide some extra classes at the module level (for example the __init__.py file defines the GenericViewError error).
This directory-level module thus "groups" interesting views together. For example the FormMixin is not exported at this level. The __init__.py here groups (popular) class-based views together, whereas the mixins, that are typically used to define such generic views, are still specific to a file.
I have a weird edge-case where I need to use the data stored in urls.py within a view, but since the urls.py file imports the view, I am getting a circular import error when I try to import the url data into the view.
cannot import name 'url_patterns'
Does Django have any way of grabbing all the url patterns within a view that could circumvent this error? The fact that the reverse() function exists indicates that it might.
You can solve this typically (well it depends a bit), by importing the urls in your view(s) locally. Like:
# urls.py
import someapp.views
url_patterns = [
url('some_url/', someapp.views.some_view),
]
and then import the urls in the views like:
# views.py
def some_view(request):
from someapp.urls import url_patterns
# ...
# do something with urlpatterns
# return response
pass
We here thus postpone the importing of the urls.py in the views, until the view function is actually called. By that time both the views.py and urls.py are (usually) already loaded. You can however not call the view in the views.py directly, since then the import is done before the urls.py is loaded.
Note that usually you do not have to import url_patterns, and you can use reverse(..) etc. to obtain a URL that corresponds to a view function (even passing parameters into a dictionary, etc.). So I really advice to look for Django tooling to handle URLs.
Found an answer:
from django.urls import get_resolver
url_patterns = set(v[1] for k,v in get_resolver(None).reverse_dict.items())