Passing parameters to a view in Django - python

In my urls.py I have set handler404 to CustomErrorView. CustomErrorView is a generic view which generates a template for an error based on the error message and error code that it receives.
Since the handler404 is only raised in the case of a 404 error, how can I send the errorcode = 404 kwarg to CustomErrorView whenever it is raised?
Already tried-
handler404 = CustomErrorView(errorcode = 404)
This causes an "Expected one positional argument, none given error."
handler404 = CustomErrorView(request, errorcode = 404)
This causes a NameError (Name 'request' is not defined)
My urls.py:
from django.conf.urls import url, include
from django.contrib import admin
from blog_user.views import home, create_error_view
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', home),
url(r'^', include('user_manager.urls')),
]
handler404 = create_error_view(error = 404)
handler500 = create_error_view(error = 500)
My views.py (after using the modifications recommended by #knbk) :
from django.shortcuts import render
from django.http import HttpResponse, HttpResponseNotFound
def create_error_view(error = 404, mybad = False):
def custom_error_view(request, error, mybad):
''' Returns a generic error page. Not completed yet. error code and messages are supposed to be modular so that it can be used anywhere for any error in the page.'''
content = "Incorrect url"
context= {
'error': error,
'content':content,
'mybad':mybad
}
response = render(request, 'error.html', context=context, status=error)
return HttpResponse(response)
return custom_error_view

You can use a function closure to create the view function:
def create_error_view(error_code):
def custom_error_view(request, *args, **kwargs):
# You can access error_code here
return custom_error_view
Then just call create_error_view to set the handler:
handler404 = create_error_view(error_code=404)
Or you can use functools.partial(), which basically does the same:
from functools import partial
handler404 = partial(custom_error_view, error_code=404)

Related

Reverse for 'about_abc' with arguments '('',)' not found

I am trying to set up web app. I am having issues with passing host_id to template .html file
i get:
Reverse for 'about_abc' with arguments '('',)' not found. 1 pattern(s) tried: ['itpassed\\/(?P<host_id>[0-9]+)\\/about\\/$']
inter.html
<li>about</li>
When i use "1" instead of "host_id" its working, but it can't stay hardcoded like this.
views.py
from django.shortcuts import render
import warnings
import requests
import json
from django.http import HttpResponse
from django.template import loader
from .models import Host
[...]
def inter(request, host_id):
return render(request, 'itpassed/inter.html')
def about_abc(request, host_id):
response = requests.get(
'abc.net:1768/abc/api/v1/about',
verify='/cert/cacerts.pem',
headers={'Accept': 'application/json', 'Authorization': 'Basic xxxxxxxxxxxxxxxxxxxxxx'},
)
return HttpResponse(response.content)
urls.py
from django.urls import path
from .models import Host
from . import views
urlpatterns = [
path('', views.index, name='index'),
path('<int:host_id>/', views.inter, name='inter'),
path('<int:host_id>/about/', views.about_abc, name='about_abc'),
]
How to fix this? As far as i can see views.py should pass host_id to template.
Why hardcoded "1" works but, host_id don't?
thanks
def inter(request, host_id):
return render(request, 'itpassed/inter.html')
You are not passing anything to the inter.html template here - so the host_id template variable won't hold any value.
I believe you want this instead:
def inter(request, host_id):
return render(request, 'itpassed/inter.html', {"host_id": host_id})

Django: handler403 doesn't work, but 404 does

Here is content of MyProj/urls.py:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('general.urls')), # Main app
]
handler403 = 'general.views.handler403'
handler404 = 'general.views.handler403'
As you can see, both handlers point to the same view, and first one, which I need most, doesn't work! For example, data of other's user at /obj/12 shows default browser 403 page:
[22/Jan/2019 08:39:14] "GET /obj/12 HTTP/1.1" 403 0
But the second one works well and shows correct page (when try to access some not existing data at /obj/768). Why and how can I solve it?
The debug mode is off. My Django version is 2.0.6
Update.
Content of the handler403.py file:
from django.shortcuts import render_to_response
def handler403(request, *args, **argv):
print('Handler 403 was called!')
u = request.user
params = {
'user': u,
}
response = render_to_response('403.html', params)
response.status_code = 403
return response
The string Handler 403 was called! is never printed when I try to get this page.
My guess is that your views returns a django.http.HttpResponseForbidden instead of raising a django.core.exceptions.PermissionDenied exception.
Only the PermissionDenied exception gets handled by handler403, a HttpResponseForbidden is returned as is.
If that's really your handler403 file (aka. handler403.py), you'll probably want
handler403 = 'general.views.handler403.handler403'
(so a dotted path to the actual callable).
handler403 should point to a view
Try something like this:
from general.views.handler403 import handler403
handler403 = handler403

Django View Error - NoReverseMatch

I am new to django and I am trying to solve a NoReverseMatch issue. I think it has something to do with the views but i'm new to this.
The code is from a popular boiler plate repo from a few years ago. PLEASE NOTE: I tried reading like every answer on stack overflow already and have been stuck for hours.
Any help would be greatly appreciated
main urls.py
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^login/', include('shopify_app.urls')),
url(r'^', include('home.urls'), name='root_path'),
url(r'^admin/', admin.site.urls),
]
urls.py inside of app
from django.conf.urls import url
from shopify_app import views
urlpatterns = [
url(r'^$', views.login, name='shopify_app_login'),
url(r'^authenticate/$', views.authenticate, name='shopify_app_authenticate'),
url(r'^finalize/$', views.finalize, name='shopify_app_finalize'),
url(r'^logout/$', views.logout, name='shopify_app_logout'),
]
views.py inside of app
from django.shortcuts import redirect, render
from django.contrib import messages
from django.core.urlresolvers import reverse
from django.conf import settings
import shopify
def authenticate(request):
shop = request.GET.get('shop')
print('shop:', shop)
if shop:
scope = settings.SHOPIFY_API_SCOPE
redirect_uri = request.build_absolute_uri(reverse('shopify_app.views.finalize'))
permission_url = shopify.Session(shop.strip()).create_permission_url(scope, redirect_uri)
return redirect(permission_url)
return redirect(_return_address(request))
def finalize(request):
shop_url = request.GET['shop']
try:
shopify_session = shopify.Session(shop_url)
request.session['shopify'] = {
"shop_url": shop_url,
"access_token": shopify_session.request_token(request.REQUEST)
}
except Exception:
messages.error(request, "Could not log in to Shopify store.")
return redirect(reverse('shopify_app.views.login'))
messages.info(request, "Logged in to shopify store.")
response = redirect(_return_address(request))
request.session.pop('return_to', None)
return response
Error
NoReverseMatch at /login/authenticate/
Reverse for 'shopify_app.views.finalize' not found. 'shopify_app.views.finalize' is not a valid view function or pattern name.
Request Method: GET
Request URL: http://localhost:8000/login/authenticate/?csrfmiddlewaretoken=zEwwHeTfxK7apbAp3dSxsehsafxqjSgEM4t&shop=piepiedev.myshopify.com&commit=Install
Django Version: 1.11.6
Exception Type: NoReverseMatch
Exception Value:
Reverse for 'shopify_app.views.finalize' not found. 'shopify_app.views.finalize' is not a valid view function or pattern name.
Source code / file structure-
https://github.com/Shopify/shopify_django_app
Similar issue but not working solution-
https://github.com/Shopify/shopify_django_app/issues/13
Change inside authenticate(request):
redirect_uri = request.build_absolute_uri(reverse('shopify_app:shopify_app_finalize'))

Error 404 handler in Django 1.9.2

I have got installed Django 1.9.2 and want to use a custom view to handle error 404. I am trying to do this:
# myapp/urls.py
from django.conf.urls import url, handler404
from django.views.generic.base import RedirectView
from django.core.urlresolvers import reverse_lazy
import views
urlpatterns = [
url(r'^not-found/$', views.NotFoundView.as_view(), name='not_found'),
]
#handler404 = RedirectView.as_view(url=reverse_lazy('not_found'))
handler404 = 'myapp.views.NotFoundView.not_found_handler'
# myapp/views/NotFoundView.py
from django.http import HttpResponse
class NotFoundView(object):
#classmethod
def as_view(cls):
return cls.handler
#classmethod
def handler(cls, request):
return HttpResponse(u"My error 404", status=404)
def not_found_handler(request, exception, template_name='404.html'):
return HttpResponse(u"New handler 404", status=404)
In other words, I overrode handler404 with RedirectView initialized by the URL to my custom view called NotFoundView. But unfortunately it didn't work, I got the standard Django's error 404 instead of my custom one. What am I doing wrong?

Django URL Routing Issue

Very new to Django, so I apologize as I'm sure this has an easy answer.
I have a PHP background, and so I guessing that I am trying to force a structure I am used to, and not one that is native in Django.
Here is my Project's urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^', include('pm.urls', namespace='pm')),
)
Here is my App's urls.py
from django.conf.urls import patterns, url
from pm import views
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
url(r'^label/add/$', views.add_label, name='label_add'),
)
I am doing an AJAX Post request to /label/add/, but it's coming back with a 500 error.
This is the views.py:
from django.shortcuts import render
from pm.models import Label
import json
# Create your views here.
def index(request):
labels_list = Label.objects.order_by('name')
return render(request, 'pm/index.html', {
'labels' : labels_list
})
""" Labels """
def add_label(request):
if request.is_ajax():
response = {
'success': True
}
else:
response = {
'success': False,
'error': "Invalid request"
}
return json.dumps(response)
Any advise or references would be great.
UPDATE
Here's the first couple of lines from the traceback I am getting:
AttributeError at /label/add/
'str' object has no attribute 'get'
you have to return HttpResponse instead of string:
return HttpReponse(json.dumps(response), content_type='application/json')

Categories