How to get keyword arguments passed in Generic views in Django - python

This is my URL
url(r'^users/(?P<pk>\d+)/testy/$', views.MyModelUpdate.as_view(model=models.User,
form_class=forms.UserForm, myVariable='testing'), name='my_update'),
This is my class view
class MyModelUpdate(UpdateView):
def get(self, request, *args, **kwargs):
How can i get myVariable here

This should do the trick:
def get(self, request, *args, **kwargs):
pk=kwargs['pk']
myVariable=self.kwargs['myVariable']

Edit
How about:
def get(self, request, myVariable, *args, **kwargs):

Related

Why can't I access request attribute inside a decorator?

I'm using request.POST.get('...') inside my Django decorator (#save_post_request) whenever my form is submitted, on each tentative I get this same error
(error with request.<anything>):
AttributeError: 'collectData' object has no attribute 'POST'
My decorator is called on top of a post() function inside CollectData classBasedView.
#views.py
class collectData(View):
template_name = 'collect_data.html'
context = {...}
def get(self, request, *args, **kwargs):
...
return render(request, self.template_name, self.context)
#save_post_request
def post(self, request, *args, **kwargs):
...
return redirect(reverse('collectData'))
#decorators.py
def save_post_request(function):
def wrap(request, *args, **kwargs):
title = request.POST.get('title') # <---
...
return function(request, *args, **kwargs)
wrap.__doc__ = function.__doc__
wrap.__name__ = function.__name__
return wrap
I'm not sure if a decorator can be called like so using classBasedViews, but I think it should be right, what is my mistake?
First argument of inner function should be self:
def save_post_request(function):
def wrap(self, request, *args, **kwargs):
title = request.POST.get('title') # <---
...
return function(self, request, *args, **kwargs)
wrap.__doc__ = function.__doc__
wrap.__name__ = function.__name__
return wrap

Django CreateView didn't return an HttpResponse object

Can't figure out why CreateView doesn't return HttpResponse. For now, I use this view just for posting (no GET). I thought that set self.success_url should be enough (as you can see in def post).
class TripCreationView(CreateView):
form_class = TripCreationForm
template_name = 'frontend/homepage.html'
def post(self, request, *args, **kwargs):
self.success_url = request.POST.get('success_url') or reverse('frontend:homepage')
super(TripCreationView, self).post(self, request, *args, **kwargs)
#
# def form_valid(self, form):
# trip = form.save(self.request)
# return HttpResponseRedirect(self.success_url)
def get_form_kwargs(self):
kwargs = super(TripCreationView, self).get_form_kwargs()
kwargs['user'] = self.request.user
return kwargs
Do you know what to do?
You forgot a return statement.
def post(self, request, *args, **kwargs):
self.success_url = request.POST.get('success_url') or reverse('frontend:homepage')
return super(TripCreationView, self).post(self, request, *args, **kwargs)

Django external api calls

I have a trouble calling external api. This is my view:
class TestView(APIView):
def call_api(self, request, *args, **kwargs):
headers = {}
url = 'http://jsonplaceholder.typicode.com/users/'
method = request.method.lower()
method_map = {
'get': requests.get,
'post': requests.post,
'put': requests.put,
'patch': requests.patch,
'delete': requests.delete
}
return Response(method_map[method](url, headers=headers, data=json.dumps(request.data)).json())
def get(self, request, *args, **kwargs):
return self.call_api(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.call_api(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return self.call_api(request, *args, **kwargs)
def patch(self, request, *args, **kwargs):
return self.call_api(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return self.call_api(request, *args, **kwargs)
This is my urls.py:
url(r'^test/(?P<pk>[0-9]+)/$', TestView.as_view()),
How can i update my urls and call_api() to get one of users: test/1/ - go to http://jsonplaceholder.typicode.com/users/1, test/2 - go to http://jsonplaceholder.typicode.com/users//2. Now i have all users in that urls.py. Also i need this for all REST requests. Thanks.
Update your call_api to
def call_api(self, request, *args, **kwargs):
headers = {}
url = 'http://jsonplaceholder.typicode.com/users/'+args[0]
# args[0] = pk

WHy use a base view in Django?

Why would one use a Base view in Django when this
from django.http import HttpResponse
from django.views import View
class MyView(View):
def get(self, request, *args, **kwargs):
return HttpResponse('Hello, World!')
can be written as
def get(request):
return HttpResponse('Hello, World!')
What is the advantage of the Base view vs the function view?
All sorts of reasons.
You want to make use of a specialized view, like the TemplateView mentioned by #pythonista that makes it a lot easier for you to write your view. e.g.,
class MyTemplateView(TemplateView):
template_name = 'template.html'
You want to have some isolation when you have similar behavior. For example, you want a class-based View to handle both the form rendering and the form post:
class MyFormView(TemplateView):
template_name = 'form.html'
def get(self, request, *args, **kwargs):
return super(MyFormView, self).get(request, *args, **kwargs)
def post(self, request, *args, **kwargs:
value1 = request.POST.get('value1')
value2 = request.POST.get('value2')
# handle the post values
return super(MyFormView, self).get(request, *args, **kwargs)
You have REST endpoint and you’d like to isolate all of the code for GET/POST/PUT/DELETE in a single class-based view.
class RestEndpoint(View):
def __init__(self):
super(RestEndpoint, self).__init__()
self.model = MyModel
def get(request, n_id, *args, **kwargs):
x = self.model.objects.get(id=n_id)
return JsonResponse(x.to_json())
def put(self, request, *args, **kwargs):
data = json.loads(request.body)
x = self.model(**data)
x.save()
return JsonResponse(x.to_json())
def post(self, request, n_id, *args, **kwargs):
data = json.loads(request.body)
x = self.model.objects.get(id=n_id)
for key, value in data.items():
setattr(x, key, value)
x.save()
return JsonResponse(x.to_json())
def delete(self, request, n_id, *args, **kwargs):
self.model.objects.filter(id=n_id).delete()
return JsonResponse({})
You just prefer using classes instead of functions, e.g., so that you can create your own fun base views and reuse code with inheritance.

turndjango class based view dispatch ValueError

My view class is like this:
class RecoedView(View):
isbn = None
def dispatch(self, request, *args, **kwargs):
self.isbn = '9754654323456'
super(RecordView, self).dispatch(request, *args, **kwargs)
def get(self, request, *args, **kwargs):
return HttpResponse('This is get')
def post(self, request, *args, **kwargs):
return HttpResponse('This is post')
When i run my view with dispatch method overridden i get rhe following error.
ValueError: The view ils.views.RecordView didn't return an HttpResponse object. It returned None instead.
Why am i getting this. Plese make me understand
You need to actually return the result of the super call.
return super(RecordView, self).dispatch(request, *args, **kwargs)

Categories