Error log:
error HomePageView' object has no attribute 'META'
urls.py
from django.conf.urls import url
from hello.views import HomePageView
urlpatterns = (
url(r'^$', HomePageView.as_view(), name='home'),
)
views.py
import textwrap
from django.shortcuts import render
from django.utils import timezone
from django.http import HttpResponse
from django.views.generic.base import View
class HomePageView(View):
def dispatch(request, *args, **kwargs):
c = {}
return render(request, 'welcome.html', c)
welcome.html
<html>
<head>
<title>Greetings to Django</title>
</head>
<body>
<h1 style="color:green;" align="center">Greetings to the world of Django Web Framework </h1>
</body>
</html>
The first parameter to dispatch, like all instance methods, should be self. request is passed as a keyword argument.
Note however that you should not be overriding dispatch. By doing so you are negating all the benefits of using class based views; you might as well use a standalone function. Instead, subclass TemplateView, set template_name as a class attribute, and define get_context_data when you actually need to pass some data to the template.
As already you are called view by name then It would be much better you can simply import all views like :
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$',HomePageView.as_view(), name='home'),
]
and mostly we use camelcase to define view name as: homePageView()
please go through it. https://docs.djangoproject.com/en/1.10/intro/tutorial01/#url-argument-name
In your views.py file, in a class function you need to use self as an argument.
Change this line def dispatch(request, *args, **kwargs): to def dispatch(self, request, *args, **kwargs):
class HomePageView(View):
def dispatch(self, request, *args, **kwargs):
c = {}
return render(request, 'welcome.html', c)
Related
greetings dear django experts,
i am having an issue with my website i am using the defualt login view in django from
from django.contrib.auth import views as auth_views
the code is working
like this inside the urls.py file :
from django.contrib.auth import views as auth_views
path('login/',auth_views.LoginView.as_view(template_name='website/login.html'), name='login-page'),
but using this methode i don't have a view inside my views.py file. the problem is i need to define a view inside my viwes.py to record logs for any one accessing this page the problem is when i tried the following code i get the error "'function' object has no attribute 'get'"
the code that gives me the error is as the following:
views.py
from django.contrib.auth import views as auth_views
def login(request):
ip = get_client_ip(request)
logger.info(f'user access: {request.user} via ip:{ip}')
return auth_views.LoginView.as_view(template_name='website/login.html')
urls.py
path('login/',views.login, name='login-page'),
.LoginView.as_view() does not process the request, it simply returns a function that will dispatch the request, you thus need to call the function that is the result of .as_view(…) with the request as parameter:
from django.contrib.auth import views as auth_views
def login(request):
ip = get_client_ip(request)
logger.info(f'user access: {request.user} via ip:{ip}')
return auth_views.LoginView.as_view(template_name='website/login.html')(request)
That being said, it looks a bit odd to do this. Why not just subclass the LoginView and register that view?
You thus can do this with:
# appname/views.py
from django.contrib.auth.views import LoginView
class MyLoginView(LoginView):
template_name='website/login.html'
def setup(self, request, *args, **kwargs):
super().setup(request, *args, **kwargs)
ip = get_client_ip(request)
logger.info(f'user access: {request.user} via ip:{ip}')
and then register your MyLoginView instead:
from appname.views import MyLoginView
path('login/', MyLoginView.as_view(), name='login-page'),
I have a Django app using djangorestframework. I want to return an empty response or nothing if the root URL is called. Below is my code.
url(r'^$', HttpResponse(''), name="redirect_to_somepage")
Expected output: [] or {}
Write a get function in your view.
view.py
from django.views.generic import View
from django.http import JsonResponse
class MyView(View):
def get(self, request, *args, **kwargs):
return JsonResponse({}, status=204)
urls.py
url(regex=r'^$', view=MyView.as_view(), name='index'),
In the last few weeks I've switched from developing an application that processes a simple XML file, then writes its contents to an Oracle DB (cx_Oracle) and outputs in HTML, to using a Django framework. The Django framework switch wasn't necessary, but since I have an opportunity to develop something by using Django, I thought why not as it is a new area for me and can't damage my CV.
Anyway, I'm having issues with knowing what to write in my urls.py file when importing a Class from the views.py file. Here are the current contents:
urls.py
from myproj.views import Pymat_program
pymatProgram = Pymat_program()
urlpatterns = (
url(r'^pymat/$', pymatProgram.abc),
)
views.py
class Pymat_program:
def abc(self, request):
test = "<html><body>Random text.</body></html>"
return HttpResponse(test)
I've tried various permutations of using request, not using request, and also how the class is called in the url tuple, all to no avail. When I use a definition outside of the class (i.e. not in any class), then this is correctly displayed in HTML.
You don't want to wrap your program in a class. (In general, in Python you should treat modules like, say, Java might treat classes with static members only.)
There are two approaches, really:
Function-based views
urls.py
from myproj.views import abc_view
urlpatterns = (
url(r'^pymat/$', abc_view),
)
views.py
def abc_view(request):
test = "<html><body>Random text.</body></html>"
return HttpResponse(test)
Class-based views
urls.py
from myproj.views import AbcView
urlpatterns = (
url(r'^pymat/$', AbcView.as_view()),
)
views.py
from django.views.generic import View
class AbcView(View):
def get(self, request, *args, **kwargs):
test = "<html><body>Random text.</body></html>"
return HttpResponse(test)
Since you are using class based views in Django, so you have to call this class in URL like:
from myproj.views import Pymat_program
pymatProgram = Pymat_program()
urlpatterns = (
url(r'^pymat/$', pymatProgram.as_view()),
)
and then use get or post methods name in class like:
class Pymat_program:
model = ModelName
def post(self, request, *args, **kwargs):
....
2nd way is to use function based views:
urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^articles/2003/$', views.view_name),
]
views.py
from django.http import HttpResponse
import datetime
def view_name(request):
now = datetime.datetime.now()
html = "<html><body>It is now %s.</body></html>" % now
return HttpResponse(html)
for more details look into class based views docs
I have this view
class UserView(GenericAPIView):
def get(self, request, format=None, **kwargs):
pass
def post(self, request, format=None, **kwargs):
pass
This works fine with this url
url(r'^user$', UserView.as_view(),name='user'),
but i want to have custom url
def custom():
pass
I want that
url(r'^user/custom/$', UserView.as_view(custom),name='user'),
How can i do that
You can't do this.
from django.conf.urls import url
from django.views.generic import TemplateView
urlpatterns = [
url(r'^about/', TemplateView.as_view(template_name="about.html")),
]
Any arguments passed to as_view() will override attributes set on the
class. In this example, we set template_name on the TemplateView. A
similar overriding pattern can be used for the url attribute on
RedirectView.
If you want a 'custom' url, Use the Functions Based views
Urls
url(r'^user/custom/$', custom, name='user'),
Views
def custom(request):
# your custom logic
# return something
Edit 1*
If you want pass parameters to the CBV.
class View(DetailView):
template_name = 'template.html'
model = MyModel
# custom parameters
custom = None
def get_object(self, queryset=None):
return queryset.get(custom=self.custom)
Url
url(r'^about/', MyView.as_view(custom='custom_param')),
I have a good many class based views that use reverse(name, args) to find urls and pass this to templates. However, the problem is class based views must be instantiated before urlpatterns can be defined. This means the class is instantiated while urlpatterns is empty leading to reverse throwing errors. I've been working around this by passing lambda: reverse(name, args) to my templates but surely there is a better solution.
As a simple example the following fails with exception:
ImproperlyConfigured at xxxx
The included urlconf mysite.urls doesn't have any patterns in it
mysite.urls
from mysite.views import MyClassView
urlpatterns = patterns('',
url(r'^$' MyClassView.as_view(), name='home')
)
views.py
class MyClassView(View):
def get(self, request):
home_url = reverse('home')
return render(request, 'home.html', {'home_url':home_url})
home.html
<p><a href={{ home_url }}>Home</a></p>
I'm currently working around the problem by forcing reverse to run on template rendering by changing views.py to
class MyClassView(View):
def get(self, request):
home_url = lambda: reverse('home')
return render(request, 'home.html', {'home_url':home_url})
and it works, but this is really ugly and surely there is a better way. So is there a way to use reverse in class based views but avoid the cyclic dependency of urlpatterns requiring view requiring reverse requiring urlpatterns...
EDIT:
I'm using this as so:
views.py
def sidebar_activeusers(cls):
sidebar_dict = {'items' = []}
qs = models.random.filter.on.users
for user in qs:
item = {
'value': user.name,
'href': reverse('user_profile', args=[hash_id(user.id)])}
sidebar = loader.get_template('sidebar.html')
cls.base_dict['sidebar_html'] = sidebar.render(Context(sidebar_dict))
return cls
#sidebar_activeusers
class MyView1(View):
base_dict = {}
...
#other_sidebar_that_uses_same_sidebar_template
class MyView2(View):
basically I'd like to use the same sidebar template for a few different content types. Although the models displayed in the sidebar will be arbitrary the format will always be the same.
For your example MyClassView, it's ok to use reverse
class MyClassView(View):
def get(self, request):
home_url = reverse_lazy('home')
return render(request, 'home.html', {'home_url': home_url},
The reverse method is not called when the class is defined -- It is only called when the request is processed and the get method is called, so there shouldn't be an error. I have tested the example above and it works fine.
However, When you use your sidebar_activeusers decorator, the reverse call occurs before the url conf is loaded. In cases like these, you can use reverse_lazy. Here's an example of reverse_lazy in action:
from django.core.urlresolvers import reverse_lazy
class MyOtherClassView(View):
home_url = reverse_lazy('home')
def get(self, request):
return render(request, 'home.html', {'home_url':self.home_url})
This time, home_url is set when the class is defined, so reverse_lazy is required instead of reverse, because the url conf hasn't loaded yet.
Your home url can be accessed directly in your template by using declaring {% url 'home' %}. It's a standard way to access your named urls in your urls.py file.
You do not have to send the home_url variable to your template explicitly in your class-based view function.
In other words, in your home.html file:-
<p>Home</p>
will do.