Views and models as python package cannot be resolved - python

I'm fairly new to Django, and I try to get the hang of using modules for views and models. Strangely enough, the URls work fine.
My app structure is
templatetags/
urls/
views/
models.py
tests.py
The views-dir has an __init__.py, and animals.py, containing one view.
from myapp.models import Animal
from django.shortcuts import render_to_response
def overview(request):
objects = Animal.objects.all()
return render_to_response('myapp/animal_list.html', {'objects': objects})
There's an animals.py in urls/, containing
from myapp.views.animals import *
urlpatterns = patterns('',
url(r'^$', 'views.animals.overview', {}, 'myapp_animal_overview'),
)
The result:
Caught ViewDoesNotExist while rendering: Could not import views.animals. Error was: No module named animals
But it's there! Can anyone see where I go wrong here? My app consists of about 10 models, hence the need for splitting.
Thank you very much in advance.

Well, generally, you don't need to import myapp.views.animals. The URL dispatcher imports the required view as necessary when the regex matches a requested URL, as per: https://docs.djangoproject.com/en/dev/topics/http/urls/#how-django-processes-a-request.
Generally speaking, I would expect your urls.py to look something like:
from django.conf import settings
from django.conf.urls.defaults import patterns, include, url # for example ...
urlpatterns = patterns('',
url(r'^$', 'views.animals.overview'),
)

You were right, I didn't need that extra import.
What did work, was
urlpatterns = patterns('',
url(r'^$', 'myapp.views.animals.overview'),
)
I needed to specify the app where the views were. Problem solved!

Related

Django: Support for string view arguments to url() is deprecated and will be removed in Django 1.10

New python/Django user (and indeed new to SO):
When trying to migrate my Django project, I get an error:
RemovedInDjango110Warning: Support for string view arguments to url() is deprecated
and will be removed in Django 1.10 (got main.views.home). Pass the callable instead.
url(r'^$', 'main.views.home')
Apparently the second argument can't be a string anymore. I came to create this code as it is through a tutorial at pluralsight.com that is teaching how to use Django with a previous version (I'm currently working with 1.9). The teacher instructs us to create urlpatterns in urls.py from the views we create in apps. He teaches us to create a urlpattern such as the following:
from django.conf.urls import url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', 'main.views.home')
]
to reference
def home(request):
return render(request, "main/home.html",
{'message': 'You\'ve met with a terrible fate, haven\'t you?'}) #this message calls HTML, not shown, not important for question
in the views.py of an app "main" that I created.
If this method is being deprecated, how do I pass the view argument not as a string? If I just remove the quotes, as shown in the documentation (https://docs.djangoproject.com/en/1.9/topics/http/urls/), I get an error:
NameError: name 'main' is not defined
I tried to "import" views or main using the code presented in this documentation:
from . import views
or
from . import main
which gave me:
ImportError: cannot import name 'views'
and
ImportError: cannot import name 'main'
I believe I've traced this down to an import error, and am currently researching that.
I have found the answer to my question. It was indeed an import error. For Django 1.10, you now have to import the app's view.py, and then pass the second argument of url() without quotes. Here is my code now in urls.py:
from django.conf.urls import url
from django.contrib import admin
import main.views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', main.views.home)
]
I did not change anything in the app or view.py files.
Props to #Rik Poggi for illustrating how to import in his answer to this question:
Django - Import views from separate apps
You should be able to use the following:
from django.conf.urls import url
from django.contrib import admin
from main import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', views.home)
]
I'm not absolutely certain what your directory structure looks like, but using a relative import such as from . import X is for when the files are in the same folder as each other.
You can use your functions by importing all of them to list and added each one of them to urlpatterns.
from django.conf.urls import url
from django.contrib import admin
from main.views import(
home,
function2,
function3,
)
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^home/$', home),
url(r'function2/^$', function2),
url(r'^$', function3),
]

Django urls.py import not detecting

I have a working api, and I am writing a UI to the API, as a separate application in the same project. My project urls.py looks like this
from django.conf.urls import *
import search
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^api/search$', search.validation),
url(r'^ui', include('ui.urls')),
)
My UI app's urls.py looks like this
from django.conf.urls import *
import views
urlpatterns = patterns('',
(r'^ui/$', views.search_template),
)
However, when I am trying to access with my browser(domain.com:8000/ui), I am getting an error.
Using the URLconf defined in api.urls, Django tried these URL patterns, in this order:
^api/search$
^ui ^ui$
The current URL, ui, didn't match any of these.
But if I use the below mapping in the main project's urls.py, it works.
(r'^ui$', ui.views.user_template),
I tried clearing the urls.pyc to make sure it is not stale, but it still persists. Please let me know what am I doing wrong.
You shouldn't repeat ui regex in the app's urls.py:
urlpatterns = patterns('',
(r'^$', views.search_template),
)

Django: Order of imports means only one views.py files is accessable

I'm just working through the DjangoBook Chapter7 tutorial on creating forms.
My issue is that I can only import one views.py file from either my books or contact directories. As a result I am only able to see the pages created by whichever views.py file is imported at the time.
I believe I need someway of differentiating between the two directories so that Django does not get confused (due to my likely bad implementation). I have also included an image of my project directory which might be useful to understand the problem.
Contact import working
from mysite.views import hello, current_datetime, hours_ahead, display_meta
from contact import views
#from books import views
urlpatterns = patterns('',
...
#url(r'^search-form/$', views.search_form),
#url(r'^search/$', views.search),
url(r'^contact_form/$', views.contact),
)
Books import working
from mysite.views import hello, current_datetime, hours_ahead, display_meta
#from contact import views
from books import views
urlpatterns = patterns('',
....
url(r'^search-form/$', views.search_form),
url(r'^search/$', views.search),
#url(r'^contact_form/$', views.contact),
)
My Project structure. I am working in Eclipse with Pydev.
Both contact and books import implemented give the below error
AttributeError at /search/
'module' object has no attribute 'search_form'
Any help is as always much appreciated.
you can use an as statement:
from contact import views as contact_views
from books import views as books_views
and the call view:
url(r'^search-form/$', books_views.search_form),
url(r'^search/$', books_views.search),
url(r'^contact_form/$', contact_views.contact),
You should put the urls.py in your application, as detailed in part 3 of the tutorial.
In your application directory create a urls.py,
contact
- __init__.py
- views.py
- models.py
- urls.py
books
- __init__.py
- views.py
- models.py
- urls.py
In book/urls.py, add the following:
from django.conf.urls import patterns, url
from .views import search, search_form
urlpatterns = patterns('',
url(r'search-form/$', search_form, name='search_form'),
)
Then in your main urls.py, add the following:
url(r'^books/', include('book.urls')),
Please go through the official tutorial as the django book website is out dated.

Django - Import views from separate apps

I'm new to Django and working my way through "The Django Book" by Holovaty and Kaplan-Moss. I have a project called "mysite" that contains two applications called "books" and "contact." Each has its own view.py file. In my urls.py file I have the following:
from books import views
from contact import views
...
urlpatterns = patterns('',
...
(r'^search/$', views.search),
(r'^contact/$', views.contact),
...
When I run my code I get this error:
NameError at /search/
...
Exception value: 'module' object has no attribute 'search'
What I believe is happening is that since views from contact was imported last, Django is looking at contact's view which does not contain search (search is in books' view).
What is the proper way to import the views.py file from two distinct applications within a Django urls file?
Thanks for your help!
Disclaimer: Not a Django answer
The problem is with these two lines:
from books import views
from contact import views
The second import is shadowing the first one, so when you use views later you're only using the views from contact.
One solution might be to just:
import books
import contact
urlpatterns = patterns('',
...
(r'^search/$', books.views.search),
(r'^contact/$', contact.views.contact),
...
I'm not sure, but I also think that you don't actually need to import anything and can just use strings in your pattern, something like: 'books.views.search'.
Another possiblity is to follow Simon Visser suggestion:
from books.views import search
from contact.views import contact
from books import views
from contact import views
You are overwriting the name views. You need to import them as different names or as absolute names.
import books.views
import contact.views
... or ...
from books import views as books_views
from contact import views as contact_views
Then use the correct name when defining your URLs. (books.views.search or books_views.search depending on the method you choose)
The reason I’m answering this question is because it was answered years ago and those answers are not correct or useful anymore for newer Django versions, or there is a better practice you should know about.
So, if you have more than one app in your Django project then you should use a new urls.py file for every one of your apps. It means that if you start a new app then you have to manually create a new file called urls.py in the subfolder of your new app. Many beginners first do not understand why this is good, but this is a good practice if you plan creating more apps in one Django project.
When you start a project, the urls.py file automatically created in your project folder, but if you create/start a new app in Django, then it is a good practice if you create a separate urls.py for that app in its own folder. (And that way you will never have the "importing different app's views into urls.py" problem in the first place).
After you created the urls.py file for your app, then you have to include that app’s urls.py file in your project’s urls.py file in the following way:
Let’s see an example when you create a new app called ‘my_new_app’.
This is how your project’s main urls.py file should look like:
from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^my_new_app/', include('my_new_app.urls')),
]
In your project’s urls.py file you have to import the ‘include’ method, then you can include your my_new_app urls.py file in your project’s main urls.py file. In your my_new_app folder you have to manually create a urls.py file as I stated above. Then you have to use that file for all of your urlpatterns of your my_new_app. Then of course this way it’s going to be automatically included in your project’s main urls.py file.
So this is then how your my_new_app own urls.py file should look like:
from django.conf.urls import url
from my_new_app import views
urlpatterns = [
url(r'^$', views.index, name = "index"),
]
Assuming that you also created a first view called ‘index’ in your ‘my_new_app/views.py file.
my_new_app/views.py file look like this:
from django.shortcuts import render
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello World!")
And you can check your my_new_app in your browser at:
http://localhost:8000/my_new_app
(Of course you can give any url to your my_new_app in your project's urls.py file.)
Now, you can create another app, in your Django project, called my_second_app and you should repeat the above steps for that app too. This way you will not have any problem importing views from different apps into urls.py files. This would be a very basic “good practice solution” for this problem in 2017 in Django 1.11.
The URLconfs documentation gives an example of the same situation
You can skip the imports and separate the urls by app as such:
urlpatterns = patterns('books.views',
(r'^/book/search/$', 'search'), #calls books.views.search
)
urlpatterns += patterns('contact.views', #make note of the '+='
(r'^/contact/search/$', 'search'), #calls contact.views.search
)
Heres the approach i took for different view/API versions:
from django.urls import path
from my_app import views as api_v1
from my_app import views_v2 as api_v2
urlpatterns = [
path('view_one', api_v1.ViewOne.as_view()),
path('view_two', api_v2.ViewTwo.as_view()),
]

Django: Simplest way to create a 2-page site?

I have a site made in PHP that i need to create a django site of. I've stripped out the PHP code temporary (not much code anyways), but i'm having problems understanding how django works and how to create a simple template to display a page.
I know there's thousands of books and guides out there, but most of them go too deep or doesn't do what i need. I just need two simple pages, page1 and page2, which will be accessed through domain.com/page1 and domain.com/page2.
What is the simplest way to achieve that?
This is what i have in my urls.py file so far, is that correct at least?
from django.conf.urls.defaults import patterns, include, url
urlpatterns = patterns('',
url(r'^$', 'mysite.views.page1', name='home'),
url(r'^$page2', 'mysite.views.page2', name='page2'),
)
It obviously doesn't work now cause the views aren't created.
Any help is greatly appreciated,
// qwerty
I recommend you to walk through tutorial, you will find out everything Django beginner should know.
Try this:
from django.conf.urls.defaults import patterns, include, url
from mysite.yourapp import views
urlpatterns = patterns('',
url(r'^$', 'mysite.views.page1', name='home'),
url(r'^page2/$', 'mysite.views.page2', name='page2'),
)
The r'^page1/$ bit is python regex
in your views.py file define your views:
def page1:
#something
This should help you get started http://docs.djangoproject.com/en/1.3/intro/tutorial01/
Well, i found the most straight-forward way is:
1) urls.py
from django.urls import include, path
from . import views
from django.views.generic import TemplateView
urlpatterns = [
path('test.html', TemplateView.as_view(template_name='main/test.html')),
]
2) templates/test.html
Hello world!
Classic 3-steps:
1) urls.py
from django.urls import include, path
from . import views
urlpatterns = [
path('test.html', views.test, name='test'),]
2) views.py
from django.shortcuts import render
def test(request):
return render(request, 'test.html')
3) templates/test.html
Hello world!
Thats more or less what I use:
urlpatterns = patterns('',
(r'^$', 'news.views.page1'),
(r'^page2/$', 'news.views.page2'),
)
just for your understanding: the beginning of a line is expressed as ^, the end as $. So ^$ stands for an empty line. more about regexp: http://docs.python.org/library/re.html
If you are using older django than direct_to_template generic view is what you need.
from django.views.generic.simple import direct_to_template
urlpatterns = patterns('',
(r'^page1/$', direct_to_template, {'template': 'page1.html'}),
(r'^page2/$', direct_to_template, {'template': 'page2.html'}),
)
Or for newer django 1.3 you need to use class based generic views
from django.conf.urls.defaults import *
from django.views.generic import TemplateView
urlpatterns = patterns('',
(r'^page1/', TemplateView.as_view(template_name="page1.html")),
(r'^page2/', TemplateView.as_view(template_name="page2.html")),
)
P.S. Don't forget to create page1.html and page2.html template files.

Categories

Resources