Before class based views my urls.py looked like that:
urlpatterns= patterns('mypackage.views',
url(r'^$', 'home', name='home'),
url(r'other', name='other'),
)
Now my home view is class based. As i like uniformity, I do not would like to keep the view class as string. I tried:
urlpatterns= patterns('mypackage.views',
url(r'^$', 'Home.as_view', name='home'),
url(r'Other.as_view', name='other'),
)
and I get Parent module mypackage.views.Home does not exist . If I simply give the class name like:
urlpatterns= patterns('mypackage.views',
url(r'^$', 'Home', name='home'),
url(r'Other', name='other'),
)
I get: __init__ takes exactly 1 argument, 2 given
Is there a way to pass a string as second argument to the url function for CBV as for FBV instead of from mypackage.views import * ?
EDIT:
There seems to be no built-in solution for this. In this case: why are strings as second parameter allowed for the url function: Doesn't it violate the zen ("there is only one way to do this)?
You should import the class-based view and specify them that way:
from mypackage.views import *
urlpatterns = patterns('mypackage.views',
url(r'^$', Home.as_view(), name='home'),
url(r'other', Other.as_view() name='other'),
)
Also note that your url() calls should have three parameters: the URL pattern, the view and name (some examples you wrote don't have all of these).
If you want to pass your view as string, then in your views do this:
class Home(View):
pass
home = Home.as_view()
then in your url:
url(r'^$', 'mypackage.views.home', name='home'),
You need to use full path.
Related
Hello thank you very much for reading my question post.
I have different url path patterns in urlpatterns,
but Django URL dispatcher(re-path) calls the same view( views.selected_verb)
for the different URL expressed by Regular expression.
These urls call the same view(views.selected_verb)
http://127.0.0.1:8000/arabic/verbs/%D9%83%D8%A7%D9%86/
http://127.0.0.1:8000/arabic/verbs/%D9%83%D8%A7%D9%86/quiz/
Would love to know how to fix it(calls different views)
here is urlpatterns
urlpatterns = [
path('', views.index, name='index'),
path('verbs', views.verbs, name='verbs'),
re_path(r'^verbs/(?P<verb>.+)/$', views.selected_verb, name='selected_verb'),
re_path(r'^verbs/(?P<verb>.+)/quiz/$', views.quiz, name='quiz'),
]
Thank you very much again!
I think the issue is that .+ will match with anything, which includes %D9%83%D8%A7%D9%86/quiz/. Maybe you could try telling it something more explicit, like [A-Z0-9%]+. When the q character comes along in quiz, it will fail matching and then go to the next url pattern which should be the one you want.
So I think it should all look like this:
urlpatterns = [
path('', views.index, name='index'),
path('verbs', views.verbs, name='verbs'),
re_path(r'^verbs/(?P<verb>[A-Z0-9%]+)/quiz/$', views.quiz, name='quiz'),
re_path(r'^verbs/(?P<verb>[A-Z0-9%]+)/$', views.selected_verb, name='selected_verb'),
]
In a django online course, the instructor has us use the url() function to call views and utilize regular expressions in the urlpatterns list. I've seen other examples on youtube of this.
e.g.
from django.contrib import admin
from django.urls import include
from django.conf.urls import url
urlpatterns = [
path('admin/', admin.site.urls),
url(r'^polls/', include('polls.urls')),
]
#and in polls/urls.py
urlpatterns = [
url(r'^$', views.index, name="index"),
]
However, in going through the Django tutorial, they use path() instead e.g.:
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name="index"),
]
Furthermore regular expressions don't seem to work with the path() function as using a path(r'^$', views.index, name="index") won't find the mysite.com/polls/ view.
Is using path() without regex matching the proper way going forward? Is url() more powerful but more complicated so they're using path() to start us out with? Or is it a case of different tools for different jobs?
From Django documentation for url
url(regex, view, kwargs=None, name=None) This function
is an alias to django.urls.re_path(). It’s likely to be deprecated in
a future release.
Key difference between path and re_path is that path uses route without regex
You can use re_path for complex regex calls and use just path for simpler lookups
The new django.urls.path() function allows a simpler, more readable URL routing syntax. For example, this example from previous Django releases:
url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive)
could be written as:
path('articles/<int:year>/', views.year_archive)
The django.conf.urls.url() function from previous versions is now available as django.urls.re_path(). The old location remains for backwards compatibility, without an imminent deprecation. The old django.conf.urls.include() function is now importable from django.urls so you can use:
from django.urls import include, path, re_path
in the URLconfs. For further reading django doc
path is simply new in Django 2.0, which was only released a couple of weeks ago. Most tutorials won't have been updated for the new syntax.
It was certainly supposed to be a simpler way of doing things; I wouldn't say that URL is more powerful though, you should be able to express patterns in either format.
Regular expressions don't seem to work with the path() function with the following arguments: path(r'^$', views.index, name="index").
It should be like this: path('', views.index, name="index").
The 1st argument must be blank to enter a regular expression.
Path is a new feature of Django 2.0.
Explained here :
https://docs.djangoproject.com/en/2.0/releases/2.0/#whats-new-2-0
Look like more pythonic way, and enable to not use regular expression in argument you pass to view... you can ue int() function for exemple.
From v2.0 many users are using path, but we can use either path or url.
For example in django 2.1.1
mapping to functions through url can be done as follows
from django.contrib import admin
from django.urls import path
from django.contrib.auth import login
from posts.views import post_home
from django.conf.urls import url
urlpatterns = [
path('admin/', admin.site.urls),
url(r'^posts/$', post_home, name='post_home'),
]
where posts is an application & post_home is a function in views.py
I have started learning Django, I'm not sure what the include() function means.
Here is mysite/urls.py. - project
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^polls/', include('polls.urls')),
url(r'^admin/', admin.site.urls),
]
Here is polls/urls.py. - app in project
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
]
From django document, include() function was described as follows.
Whenever Django encounters include(), it chops off whatever part of the URL matched up to that point and sends the remaining string to the included URLconf for further processing.
I'm not sure what is that point, what is remaining string.
In case of the example above, what is remining string, what is url strings which was chopped off?
For example, from this URL:
polls/5/results
the URL rule:
url(r'^polls/', include('polls.urls')),
chops off the polls/ part of URL and sends the remaining string after polls/, whatever it might be, for example (see here more):
5/results/
to urls from the poll app's urls.py, where it will then be mapped to a view based on the URL rules defined in this file
Whenever it will encounter any url with /polls then it will include all the urls of polls app.
Example:
If you type /polls/hey
Then as soon as it sees /polls it will go to polls urls file and later it will search for:
hey/ matching over there.
Lets say there is one more entry in your polls/urls.py like
url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
here year is the query string parameter. so your url will look like
/polls/articles/2007 so in this case /polls/articles/ will matched up and 2007 will pass to year_archive method
In your example there is no chopped string, the URL comes back as simply polls/, but when you have another url such as '^new$' then that url is being chopped, merged with polls/ and it returns polls/new, hope this makes sense..
I am new to Django and I am trying to understand it. If I write a url pattern like this
url(r'^$', 'newsletter.views.home', name='home'),
it works. and If I write it like this
url(r'^$', 'newsletter.views.home'),
it still works, but I get the following data from the server
RemovedInDjango110Warning: Support for string view arguments to url() is deprecated and will be removed in Django 1.10 (got newsletter.views.contact). Pass the callable instead.
url(r'^contact/$', 'newsletter.views.contact'),
My first question is what does the third argument do. the
name='home' or name='contact'. What is it reffering to.
and my second question is what does
Pass the callable instead.
mean? Again, I have read the docs and came here for a bit more clarity in laymen's terms. All help and advice is welcome
When it says pass the callable, it means you should import the view itself and include that in your url pattern.
from newsletter.views import home
url(r'^$', home, name='home'),
Another option is to import the views module itself
# renaming allows us to import more than one views at once
from newsletter import views as newsletter_views
url(r'^$', newsletter_views.home, name='home'),
Naming url patterns allows you to reverse url patterns (e.g. go from a name to a url). This means you don't have to hardcode urls in your views and templates.
If you have
url(r'^home/$', home, name='home'),
then you can use reverse('home') in your code, and {% url 'home' %} in your templates, instead of writing /home/ repeatedly.
I am trying to use Django generic view for CRUD.
I found two resources (1, 2), and bit confused the best and easy approach.
Added below to myapp/urls.py
urlpatterns = patterns('',
url(r'^$',
ListView.as_view(
model= Product)),
)
then it gave an error that,
Exception Type: TemplateDoesNotExist
Exception Value:
myapp/product_list.html
It worked when I created a file product_list.html. But, do I have to manually write the template? I am sure not.
Also, how to decorate it so that only users of a group has access to it.
Thanks.
The decorator can be applied inside the urlpatterns like so:
urlpatterns = patterns('',
url(r'^$', my_decorator(ListView.as_view(model= Product))),
)
Yes you have to manually write the template.
Also the name of the template is the_model_name_list.html by default but you can also define a custom template name like so:
urlpatterns = patterns('',
url(r'^$', my_decorator(ListView.as_view(model= Product,
template_name="custom_name.html"))),
)