The callback function object in Django URLconf is not called - django

I am learing Django on Django at a glance | Django documentation | Django
When introducing URLconf It reads:
To design URLs for an app, you create a Python module called a URLconf. A table of contents for your app, it contains a simple mapping between URL patterns and Python callback functions.
Nevertheless, a callback function is not called.
mysite/news/urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^articles/([0-9]{4})/$', views.year_archive),
]
print('callback funtion:',views.year_archive)
output:
callback function: <function views.year_archive at 0x1039611e0>
So it a funtion object which is not called.
I suppose it should be views.year_archive() to enable it to call.
If not called,how does it work? I assume there a decorator to process it in parent class.
I check the source codes of urldjango.conf.urls | Django documentation | Django
The key statement is:
elif callable(view):
return RegexURLPattern(regex, view, kwargs, name)
I dig on to explore LocaleRegexProvider, RegexURLPattern django.urls.resolvers | Django documentation | Django.
No appopriate codes were found to call the callback function views.year_archive
What's the mechanism of its working?

Django automatically calls the callback view function whenever a request is made to the given url pattern.
To understand how it works, look at this example:
>>> def a():
print("Called function a")
>>> def b():
print("Called function b")
>>> def c(callback):
# call the callback function like this
callback()
>>> c(a)
Called function a
>>> c(b)
Called function b
Basically, this is how Django's url function works.

Related

How to generate Django request object with ASGIHandler class programmatically

I have a Django project in which I have a function called some_func that uses request inside it.
from fastapi import Depends
from fastapi.security import HTTPBasicCredentials
def foo(credentials: HTTPBasicCredentials = Depends(security),):
# Need to generate a request object
user = some_func()
def some_func(request):
x = request.GET.get('my_param')
Unfortunately, I have no chance to edit the some_func function and the only solution is to generate an empty Django request object. I looked into the ASGIHandler class, method create_request, but I couldn't figure out how to set scope and body_file params.

function or class from url

I use django as a backend. I have big project and there are many views(ViewSets from django-rest-framework, views and functions). And I use React as a front and and how can I get function or class which will be called from the url. For example I have the url:
api/v2/users/322/send_letters/1232/
from this url I want to know which class or function will be called.
I think you're looking for resolve() that can be used for resolving URL paths to the corresponding view functions.
Be careful when using resolve(path) the function raises a Resolver404 if the URL does not resolve (Doesn't exist in your all URLs patterns)
>>> from django.core.urlresolvers import resolve
>>> path = 'api/v2/users/322/send_letters/1232/'
>>> match = resolve(path)
>>> match.url_name
>>> 'url_name'
>>> match.view_name
>>> match.func # func, that you are looking for
match.view_name will return the name of the view that matches the URL, including the namespace if there is one.

Url maps operation in Django

i'm new to django and i'd like to know how the url maps work in detail.
from django.conf.urls import url
from polls import views
urlpatterns =[
url(r'^$',views.index,name='index')
]
the url function takes 3 parameters, could you explain how they work and what functionalies they have.
I've searched for this, but no detailed information are available for an absolute beginner
The Django URL dispatcher contains urlpatterns which is a Python list of url() instances.
The url(regex, view, kwargs=None, name=None) function can take 4 arguments:
regex: Regular expression, pattern matching the url.
view: View name, path, function or the result of as_view() for class-based views. It can also be an include().
kwargs: Allows you to pass additional arguments to the view function or method.
name: Naming URL patterns.

Django running wrong view method

I have to view files stored in mysite folder. one is named as views.py and other is named as request_view.py. In urls.py, I have used 'answer' method for views.py and 'display_meta' method for request_view.py.
(django version: 1.5 and python version: 2.7.3)
this is the url pattern:
url(r'^twitter/$', answer), url(r'request/$', display_meta)
when I call http:/127.0.0.1:8000/request/, then also first view(i.e. /twitter/) is called!
any help?
one more thing. In my view.py, I have some unbounded code (i.e. the code which is neither present in a method or class). can this be the cause of the problem?
l = StdOutListener()
auth = OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
stream = Stream(auth, l)
keyword = input('enter the keyword you want to search for?')
stream.filter(track = [keyword])
apart from this code, evry code is either in the class or method.
One thing that I noticed is that first the code of the view.py runs, then display_meta runs.
Thanks in advance.
SOLVED
The problem was with the import function that I was using. since my code was unbounded in one of the views, the import function always import that regardless of the url that I choose.
Suggestion
Always use the nomenclature mentioned in the this example. In many books it has been suggested that we should import the views, but it might cause an error if you have unbounded code like I had.
I don't know exactly why /twitter/ view is called, but I can see two things to change:
You should use a string as the second parameter for url(), as you can see in this example [1]. You can use 'myapp.views.my_method' nomenclature.
You forgot to start the request URL with ^ that indicates the start of the URL.
About the unbounded code, I don't know if that could be causing the problem. But I can't see why are you putting that code unbounded. I am not sure when that code would be executed, I guess the first time you call a view in that file and Django loads the file (I'm guessing, I don't know exactly), but I don't think that would be a good way to do that. Think when do you want to execute that code, put it in a method, and call it.
[1] https://docs.djangoproject.com/en/1.5/topics/http/urls/#example
HI hemant i am wondering why you have written request_view.py.
Please see the django docs.
what you can do is .
Create two function in your views.py like
def answer(request):
do some stuffs.
render_to_response(template.html)
and on the same page write another
def display_meta(request):
# do your studd
render_to_response(some.html)
YOU NEED NOT TO CREATE TWO SEPERATE VIEWS.PY
I dont know what this code does
l = StdOutListener()
auth = OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
stream = Stream(auth, l)
keyword = input('enter the keyword you want to search for?')
stream.filter(track = [keyword])
But if you want to use StdOutListener inside your function you can call in your view
like
def display_meta(request):
stobject = StdOutListener() # use parameters if you have here
# do your studd
render_to_response(some.html)
Organizing views into a python package could solve this problem. So if you have a structure like this...
# views.py
def SomeView(request):
return HttpResponse('SomeView')
# another_view.py
def AnotherView(request):
return HttpResponse('AnotherView')
Your can reorganize these separate view files into a views package. That is...
# views
# __init__.py
from views import SomeView
from another_view import AnotherView
# views.py
def SomeView(request):
return HttpResponse('SomeView')
# another_view.py
def AnotherView(request):
return HttpResponse('AnotherView')
And now, everything can be called in a django-standard way:
url(r'^url-to-some-view/$', 'views.SomeView'),
url(r'^url-to-another-view/$', 'views.AnotherView'),
UPDATED:
To make a 'python package'...
Create a views directory at the same level as the view.py file [mkdir views]
Create a __init.py__ file inside the views directory # this is what makes a directory a 'python package'
Move views.py into the views directory.
Move your request_view.py into the views directory.
Edit the __init__.py file with the necessary import statements. In this case:
from views import answer
from request_view import display_meta
What this does is replace a file with a directory. By importing everything into the __init__.py file, this directory looks like a large file to your code, rather than another module.

Adding extra_context in Django logout built-in view

In django/contrib/auth/views.py there is the definition of the logout view :
def logout(request, next_page=None,
template_name='registration/logged_out.html',
redirect_field_name=REDIRECT_FIELD_NAME,
current_app=None, extra_context=None):
I would like to add extra_context to get rid of the 'Logged out' title that appear when I log off
so I'm trying this in my url confs :
(r'^accounts/logout/$', logout(extra_context={'title':'something else'}) ),
but then I get this error : logout() takes at least 1 non-keyword argument (0 given)
what I'm doing wrong?
ps:
when I do
(r'^accounts/logout/$', logout ),
it works, but then I get the 'Logged out' text...
Thanks,
Fred
When you write logout(extra_context={'title':'something else'}), you're actually calling logout right there in the URLconf, which won't work. Any URLconf tuple can have an optional third element, which should be a dictionary of extra keyword arguments to pass to the view function.
(r'^accounts/logout/$', logout, {'extra_context':{'title':'something else'}}),
Alternatively, you could write your own view which calls logout passing in whatever arguments you want -- that's typically how you would "extend" function-based generic views in more complicated cases.
Adding my findings for django 2.0 as the previous answer on this thread no longer works for the most recent django version.
With 2.0, the proper way of adding a URL to your urls.py file is by using path():
from django.urls import path
from django.contrib.auth import views as auth_views
path('accounts/logout/', auth_views.LogoutView.as_view(
extra_context={'foo':'bar'}
)),
The code snippet to highlight here is the .as_view() function. Django 2.0 implements auth views as classes. You can read more about this in the Authentication Views documentation
You then "convert" the class to a view using `.as_view() and you are able to pass in any class attributes defined in the source code as named parameters.
Passing in extra_context (which defaults to None) automatically exposes these context variables to your templates.
You can access the source code for LogoutView by following this python path: django.contrib.auth.views
Here you can see the other class attributes you can pass into LogoutView and the other auth view classes.
I had a similar problem with titles and generic views in django 1.11 (though the problem was mostly that I didn't switch docs version from 2.0). I wanted to pass title via extra_context to the view inherited from CreateView, and discovered that django's generic view had no such attribute. So, here are my crutches:
Create custom mixin (hope that's more or less what ContextMixin in 2.0 does):
class ExtraContextMixin():
extra_context = {}
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update(self.extra_context)
return context
Add mixin to view's ancestors (that's all code I had to change):
class CustomView(ExtraContextMixin, CreateView):
Pass extra_context from url:
url(r'^custom-view/$', views.CustomView.as_view(extra_context={'title': 'just any'}), name='custom-view')
Unfortunately, I have no idea whether such solution is acceptable (no need since 2.0, obviously), but at least it's working.