Can you have a view function in your URLS.py file - python

This is just an academic question. I don't intend this for production but can you put a view function above your url routes in your url.py file? Something like:
from django.conf.urls import patterns, include, url
from django.http import HttpResponse
def hello_world(request):
return HttpResponse("Hello World!")
urlpatterns = patterns('',
url(r'^$', 'hello_world'),
)

Yes, the view can be in your urls file, although I wouldn't recommend it as a way to organise your Django project.
However, in the url() you should use the view itself, not a string.
urlpatterns = [
url(r'^$', hello_world),
]
Providing string view arguments e.g. 'myproject.urls.hello_world' is deprecated in Django 1.8 and removed in Django 1.10.
The view argument can be any callable, you can even use a lambda function (again, I wouldn't recommend it).
urlpatterns = [
url(r'^$', lambda req: HttpResponse("Hello World"),
]

Related

Django beginner define an index url and load the view

I am learning django and I am trying to add a new url to '/'
here is my urls.py:
from django.contrib import admin
from django.urls import path
from blog import views as blog_views
urlpatterns = [
path(r'^$', blog_views.index),
path('admin/', admin.site.urls),
]
and here is the index method from blog/views:
def index(request):
return HttpResponse("Hey There")
But when I go to '/' route, I get a 404 response. It seems that it fails at import from blog import views as blog_views in urls.py.
What is going wrong?
Here is my project structure:
Here is the error I get:
In Django 2.x there is a path function instead of django's 1.x url function
the path function doesn't accept Regular Expressions it only accepts normal text
So to make a url for the home page with path function you only need to write your url path like this :
urlpatterns = [
path('', blog_views.index), # http://localhost/
path('admin/', admin.site.urls),
]
read more about Django 2.x urls here:
https://docs.djangoproject.com/en/dev/ref/urls/

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),
]

What more do I need to do to have Django's #login_required decorator work?

I am trying to use Django's account system, including the #login_required decorator. My settings.py file includes django.contrib.auth and I have done a syncdb.
Page not found (404)
Request Method: GET
Request URL: http://localhost:8000/accounts/login/?next=/
Using the URLconf defined in dashboard.urls, Django tried these URL patterns, in this order:
^$ [name='home']
The current URL, accounts/login/, didn't match any of these.
You're seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page.
I see the above after trying to #login_required-decorate my home view.
It seems to be choking because it is redirected to accounts/login/, which I have not prepared for in my urls.py.
What can I add to urls.py or elsewhere so that the login_required decorator will do its usual behaviour?
Thanks,
Set the LOGIN_URL in your settings. The default value is '/accounts/login/'
The decorator also takes an optional login_url argument:
#login_required(login_url='/accounts/login/')
And, from the docs:
Note that if you don’t specify the login_url parameter, you’ll need to
ensure that the settings.LOGIN_URL and your login view are properly
associated. For example, using the defaults, add the following line to
your URLconf:
(r'^accounts/login/$', 'django.contrib.auth.views.login'),
path('accounts/login/', admin.site.urls),
Add this line in your urls.py project folder. Then it will work fine.
from django.contrib.auth.decorators import login_required
#login_required(login_url='/accounts/login/')
Add above two lines in your views.py file.
What worked for me in Django 2.2.1 - include re_path('^accounts/', admin.site.urls), in my project urls.py:
urls.py
from django.conf import settings
from django.conf.urls import include
from django.conf.urls import re_path
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path
urlpatterns = [
path('admin/', admin.site.urls),
re_path('^accounts/', admin.site.urls),
]
And in my views.py:
views.py
from django.contrib.auth.decorators import login_required
from django.views.generic import TemplateView
#method_decorator(login_required, name='dispatch')
class HomePageView(TemplateView):
"""
Home Page View
"""
template_name = 'amp/home.html'
Hope that helps.
UPDATE: To avoid warnings from django in regards to admin urls being loaded twice, I used a redirect instead in urls.py:
urls.py
urlpatterns = [
re_path('^accounts/', admin.site.urls),
re_path(r'^admin/', RedirectView.as_view(url='/accounts/', permanent=True))
]
More on redirect view here.

Django SSLRedirect non-keyword arg after keyword arg

I am trying to to redirect some of my Django views to https, using the SSLRedirect middleware.
I created the middleware, but I'm having trouble securing specific url paths as described in the middleware snippet. When I add {'SSL':True} to my view keywords, I get this syntax error: 'non-keyword arg after keyword arg'. My urls.py is
from django.conf.urls.defaults import patterns, include, url
from django.views.generic.simple import direct_to_template
from post.views import *
urlpatterns = patterns('',
url(r'^$', turk_post, name='post', {'SSL':True}),
)
Replace:
url(r'^$', turk_post, name='post', {'SSL':True}),
with:
url(r'^$', turk_post, name='post', kwargs={'SSL':True}),
The Django url is a function defined like this:
def url(regex, view, kwargs=None, name=None, prefix=''):
# et cetera
(hence your error as the function expects a keyword argument)

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