Django unexpected keyword argument 'id' - python

i'm trying to use arguments on django but when middleware is working on the views.py function, it returns me this error: call() got an unexpected keyword argument 'id'.
views.py function
from django.http import HttpResponse
from .middleware import SampleMiddleware
#SampleMiddleware
def myfunc(request, id):
return HttpResponse(id)
This is my middleware
class SampleMiddleware(object):
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
return response
This is the URL
path('myfunc/<id>', views.myfunc, name='myfunc'),

A middleware class isn't a decorator. In order to use it as one you'd have to wrap it with the decorator_from_middleware utility.

Related

Why I get an error when adding __init__(self) method to Django rest framework viewset class?

I Am keep getting a error when trying to build a Django API.
I have this class:
from uuid import UUID
from django.shortcuts import render
from django.http.response import JsonResponse
from django.http.request import HttpRequest
from rest_framework import viewsets, status
from rest_framework.parsers import JSONParser
from rest_framework.response import Response
from Instruments import serializers
from Instruments.services import InstrumentsService
from rest_framework.decorators import api_view
from Instruments.services import InstrumentsService
from Instruments.models import Instrument
from Instruments.serializers import InstrumentsSerializer
# Application views live here
class InstrumentViewSet(viewsets.ViewSet):
# instruments = Instrument.objects.all()
def __init__(self):
# self.instrument_service = InstrumentsService()
# self.instruments = Instrument.objects.all()
super().__init__()
def list(self, request: HttpRequest):
try:
self.instruments = Instrument.objects.all()
serializer = InstrumentsSerializer(self.instruments, many=True)
# data = self.instrument_service.get_instruments()
data = serializer.data
return JsonResponse(data, status=status.HTTP_200_OK, safe=False)
except Exception as exc:
return JsonResponse(
{"Status": f"Error: {exc}"},
status=status.HTTP_400_BAD_REQUEST,
safe=False,
)
when the init() method is defining even if it is just doing pass the django server gives me this error when I send a request:
TypeError at /api/
__init__() got an unexpected keyword argument 'suffix'
If I remove or comment out the init() method it works.why??
The “got an unexpected keyword argument” exception is rather descriptive. What it means is your class instance (in this case, your ViewSet instance) was initialized with a keyword argument that you’re not handling. That can be fixed by doing the following in your init method:
def __init__(self, **kwargs):
# self.instrument_service = InstrumentsService()
# self.instruments = Instrument.objects.all()
super().__init__(**kwargs)
This is required because the super class (View) utilizes **kwargs when the instance is initialized.
For the record, this is not using Django as it was intended. Django was never meant for service layers and using the init method like this is counterproductive since a ViewSet takes a queryset variable. I would encourage you to read the documentation much more thoroughly before continuing with this project of yours.

Issue with missing "request" in django function

I have a little question about request attribute in my function located in a python file (not my view):
def my_function(model, request):
instance = model.objects.filter(application=request.cur_app, display=True).order_by('order')
return instance
In this same file, I call my function like this:
for element in my_function(my_model):
... do something ...
But I get this issue:
my_function() missing 1 required positional argument: 'request'
I don't understand How I can solve this issue, because if I add 'request' in my loop, I get:
name 'request' is not defined
Thank you !
Update:
I have a middleware.py file which contains this:
class MultiSiteMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
request.cur_app = WebApplication.objects.get_current(request)
return self.get_response(request)
And this is this middleware that I want to get in my menu.py file in this function:
def list_of_edition():
""" Return list of editions
:return queryset
"""
instance = NavbarMenuSettings.objects.filter(application=MultiSiteMiddleware, display=True).order_by('order')
return instance
When you run this function
my_function
you must given two params model and request
model = ...
request = ...
my_function(model,request)
django function base view 1st positional argument is request,
def funtionbaseview(request, arg1, arg2)

Using custom class view in django get me error

I'm learning django and i'm trying to create my own custom class in a views.py file
This class i would use have to method, one for classical HTML rendering, and another for json response
my class in views.py
class myListView():
context = {}
def __init__(self, request):
request = request
context['PageTitle'] = 'Contacts'
context['people'] = People.objects.all()
def htmlRender(self, *args, **kwargs):
context['children_template'] = 'people/list.html'
return render(request,'base.html',context)
def jsonRender(self, *args, **kwargs):
return HttpResponse(json.dumps(self.context['people']), content_type="application/json")
my urls.py
path('list', login_required(myListView.htmlRender()), name='list'),
path('list/json', login_required(myListView.jsonRender()), name='list'),
Here is the error sended by debugger :
TypeError: htmlRender() missing 1 required positional argument: 'self'
I don't have any idea how to solve this, maybe i'm dreaming about using custom class in view ?
Thanks'you
from django.views.generic import ListView
class myListView(ListView):
Maybe you are not extending the ListView Class, try this out.
You should first create an instance from "myListView" class then use it :
myListViewInstance = myListView(arguments)
myListViewInstance.htmlRender()

Django 1.6: NoReverseMatch at /sitemap.xml

I'm trying to implement django sitemaps but i get the following error. I don't know what I'm doing wrong. Here is the relevant code and traceback.
File "mysite/sitemap.py" in location
20. return reverse(obj)
File "/Library/Python/2.7/site-packages/django/core/urlresolvers.py" in reverse
532. return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
File "/Library/Python/2.7/site-packages/django/core/urlresolvers.py" in _reverse_with_prefix
452. (lookup_view_s, args, kwargs, len(patterns), patterns))
Exception Type: NoReverseMatch at /sitemap.xml
Exception Value: Reverse for 'name_of_url' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []
here is sitemap.py file
from django.contrib.sitemaps import Sitemap
from django.core.urlresolvers import reverse
from meddy1.models import Doctor
import datetime
class Sitemap(Sitemap):
def __init__(self, names):
self.names = names
def items(self):
return self.names
def changefreq(self, obj):
return 'weekly'
def lastmod(self, obj):
return datetime.datetime.now()
def location(self, obj):
return reverse(obj)
class DoctorSitemap(Sitemap):
changefreq = "Daily"
priority = 1
def items(self):
return Doctor.objects.all()
def lastmod(self, obj):
return obj.date
here is urls.py file
url(r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps}),
If you read carefully the documentation:
https://docs.djangoproject.com/en/1.6/ref/contrib/sitemaps/#django.contrib.sitemaps.Sitemap.location
You will find out that Django calls get_absolute_url for the each Sitemap object (unless you have location specified).
You define localtion with: reverse(obj) where does that point exactly? Your reverse should point to a valid registered url. Additionally where exactly did you read that location receives an argument? location is either an attribute or a method that returns a path (no arguments required).
Your error is not sitemaps related, but rather url resolution inside your registered sitemap models.
Finally what is the exact purpose of the Sitemap Class you define?

Conditional Django Middleware (or how to exclude the Admin System)

I want to use some middleware I wrote across the whole of my site (large # of pages, so I chose not to use decorators as I wanted to use the code for all pages). Only issue is that I don't want to use the middleware for the admin code, and it seems to be active on them.
Is there any way I can configure the settings.py or urls.py perhaps, or maybe something in the code to prevent it from executing on pages in the admin system?
Any help much appreciated,
Cheers
Paul
The main reason I wanted to do this was down to using an XML parser in the middleware which was messing up non-XML downloads. I have put some additional code for detecting if the code is XML and not trying to parse anything that it shouldn't.
For other middleware where this wouldn't be convenient, I'll probably use the method piquadrat outlines above, or maybe just use a view decorator - Cheers piquadrat!
A general way would be (based on piquadrat's answer)
def process_request(self, request):
if request.path.startswith(reverse('admin:index')):
return None
# rest of method
This way if someone changes /admin/ to /django_admin/ you are still covered.
You could check the path in process_request (and any other process_*-methods in your middleware)
def process_request(self, request):
if request.path.startswith('/admin/'):
return None
# rest of method
def process_response(self, request, response):
if request.path.startswith('/admin/'):
return response
# rest of method
You don't need to muck around with paths.
If you want to exclude a single middleware from a view, you must first import that middleware and do:
from django.utils.decorators import decorator_from_middleware
from your.path.middlewares import MiddleWareYouWantToExclude
#decorator_from_middleware(MiddleWareYouWantToExclude)
def your_view(request):
....
If you want to exclude ALL middleware regardless of what they are/do, do this:
from django.conf import settings
from django.utils.module_loading import import_string
from django.utils.decorators import decorator_from_middleware
def your_view(request):
...
# loop over ALL the active middleware used by the app, import them
# and add them to the `decorator_from_middleware` decorator recursively
for m in [import_string(s) for s in settings.MIDDLEWARE]:
your_view = decorator_from_middleware(m)(your_view)
middleware functions are basically called for every request, including image src, api, form, ajax calls etc. somehow people reckon it is only called before and after view. This not only can cause performance concern, but also is hard to change.
I do not recommend path comparison unless using reverse, on the one hand, reference modification may create more trouble; on the other hand, if conditionals seems messy.
here I provide a solution for converting middleware to decorator, this method requires you to add decorator manually to all views. Fully optimised, you can make decisions which right middleware is for the right view
before I had:
class AjaxMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
def is_ajax(self):
return request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'
request.is_ajax = is_ajax.__get__(request)
response = self.get_response(request)
return response
class DeletionMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
from staff.models import Deletion
response = self.get_response(request)
Deletion.auto_clean_up()
return response
MIDDLEWARE = [
'common.middleware.DeletionMiddleware',
'common.middleware.AjaxMiddleware',
]
now I created a decorators.py:
from django.contrib.auth.models import User
class Shape:
#staticmethod
def before(request):
pass
#staticmethod
def after(request):
pass
# All default to call, pass in as excluder param to escape
# Part default not to call, pass in as includer param to execute
class All(Shape): pass
class Part(Shape): pass
class Mixins:
class Online(Part):
#staticmethod
def after(request):
if request.user.is_authenticated:
request.user.profile.visit()
class Deletion(All):
#staticmethod
def after(request):
from staff.models import Deletion
Deletion.auto_clean_up()
class Ajax(All):
#staticmethod
def before(request):
def is_ajax(self):
return request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'
request.is_ajax = is_ajax.__get__(request)
def common_dec(excluders=[], includers=[]):
def common(function):
# def wrapper_func(*args, **kwargs):
# return function(*args, **kwargs)
# return wrapper_func
"""
common view that returns a template
does not incldue images and cdn access
"""
def wrapper_func(request, *args, **kwargs):
# iterate all classes in Mixins
alls = All.__subclasses__()
parts = Part.__subclasses__()
list(map(lambda cls:cls.before(request) if cls.__name__ not in excluders else 0, alls))
list(map(lambda cls:cls.before(request) if cls.__name__ in includers else 0, parts))
response = function(request, *args, **kwargs)
list(map(lambda cls:cls.after(request) if cls.__name__ not in excluders else 0, alls))
list(map(lambda cls:cls.after(request) if cls.__name__ in includers else 0, parts))
return response
return wrapper_func
return common
def common_mix(excluders=[], includers=[]):
class CommonMixin:
def dispatch(self, request, *args, **kwargs):
alls = All.__subclasses__()
parts = Part.__subclasses__()
list(map(lambda cls:cls.before(request) if cls.__name__ not in excluders else 0, alls))
list(map(lambda cls:cls.before(request) if cls.__name__ in includers else 0, parts))
response = super().dispatch(request, *args, **kwargs)
list(map(lambda cls:cls.after(request) if cls.__name__ not in excluders else 0, alls))
list(map(lambda cls:cls.after(request) if cls.__name__ in includers else 0, parts))
return response
return CommonMixin
which I can do
# common_dec implement all Shape.All middleware
#common_dec()
def index(request):
return render(request, 'index.html')
# this will except Deletion middleware, and include Online middleware, and execute all Shape.All
#common_dec(['Deletion'], ['Online'])
def index(request):
return render(request, 'index.html')
for class based view:
# this will execute all Shape.All, and include Online which is a Shape.Part
class ArticleDetailView(common_mix(excluders=['Online']), LoginRequiredMixin, DetailView):
pass
I have give up middleware since it lacks flexibility, this method largely saves performance and is implementable for large scopes view definition, will not causing any bug.
if you want to add a middleware, simply add a class to Mixin inheriting Shape.All, then it will be called for all decorated view function and classes. if you have a new type of view function that needs a new middleware, define it as Part and include it in decorator .it is also extremely convenient to exclude some middleware in particular view.

Categories