Alternative of Requests in django - django

In my project I'm trying to hit a url(which is running in same project) in my view.
so in simplest way I can explain here.
#login_required
def my_api_view(request):
if requests.method == 'GET':
# do stuff
return JsonResponse()
# and its url is `/api/get-info/`
another view which is consuming above api
#login_required
def show_info(request):
url = get_base_url + /api/get-info/ # http://localhost:8000/api/get-info/
r = requests.get(url)
return HttpResponse(r.json())
Now I have to use same session (login required) so when I hit the url using requests it complains that user is not loggedin which is obviously correct.
How can I do this elegantly and efficienty. session use of logged in user. (I dont want to call the view as a function, I want to hit the api-url end point and consume.
PS: we have something similar in django Test self.client.get(...)

Just call that view function and pass the request object as parameter to it.
#login_required
def show_info(request):
r = my_api_view(request)
return HttpResponse(r.json())
Or a better option would be to simply separate the logic into a separate function, as mentioned by #koniiiik in the comments.
EDIT: Or if you really want to hit the URL endpoint, you can simply pass on the cookie values to the request you make.
#login_required
def show_info(request):
url = get_base_url + "/api/get-info/" # http://localhost:8000/api/get-info/
r = requests.get(url, cookies=request.COOKIES)
return HttpResponse(r.json())

Related

How can I hit Django api with parameters using Postman?

#must_be_admin_user
def patch(self,request,category_id):
'''
Updates Data in the Category
Parameters
Authenticated Admin User , category_id
'''
category = get_object_or_404(Category, id=category_id)
# IF admin is not the Creater of the Category
if category.created_by != request.user.id:
Response(status=status.HTTP_400_BAD_REQUEST, data={"error": "You did not Create this so you cant delete this"})
category.last_updated = timezone.now()
updated_category = CategorySerializer(
category, data=request.data, partial=True)
if updated_category.is_valid():
updated_category.save()
return Response(status=status.HTTP_201_CREATED, data=updated_category.data)
return Response(status=status.HTTP_400_BAD_REQUEST, data={"error": updated_category.errors})
I want to know how to send category_id using postman .
I am facing issues hitting this api using postman
If your the URL pattern for this view is called, for instance 'patch', you could:
from django.urls import reverse
# Use the resulting url in Postman. This is what I use in tests.
url = reverse('patch', args=(some_id_here,), kwargs={})
You can use this technique for every view you have.
More here
Another thing you have to be aware of is that the user performing this request has to be logged in as admin, so you have set Postman cookies accordingly.
I recommend the use of a google chrome extension called "Postman Interceptor"
Good luck!

Return HttpResponse object and render page from Django views.py

I'm new to Django and have been learning by modifying some existing code. The original code, in the views.py file, had a method that returned an HTTP Response object (lets call this resp) to the browser, on the click of a button.
I want to be able to
open a new page on a click of that button (which I am doing using the render() function)
as well as
pass resp to it (this is because the 3rd party API that I am using needs this HttpResponse object in order to work).
Is there anyway I can do this? I thought of passing resp as part of the context parameter in the render() function, but I don't understand how I can collect back the value from this context dictionary and then return it to the browser.
EDIT: This is the code in the views.py file:
def call(request):
"""Returns TwiML instructions to Twilio's POST requests"""
response = Dial(caller_id=settings.TWILIO_NUMBER)
# If the browser sent a phoneNumber param, we know this request
# is a support agent trying to call a customer's phone
if 'phoneNumber' in request.POST:
response.number(request.POST['phoneNumber'])
else:
# Otherwise we assume this request is a customer trying
# to contact support from the home page
response.client('support_agent')
response = str(response)
probe = response.find(">")
response = response[:probe+1] + "<Response>" + response[probe+1:] + "</Response>"
print('response:', response)
context = {'response': HttpResponse(response)}
return render(request, 'browser_calls/call_in_progress.html', context) # originally HttpResponse(response) was being returned here because that was required for the call to be placed
What you can do is return all the variables from that scope using locals()
context = locals()
return render(request, template, context)

django redirect does not work

I wanted to have function that every time get the request and check that user is login and then return user object if user is login otherwise redirect to login , so this is what I tried to do
def is_login(request):
userID = request.session.get('mainSession', 0)
next = resolve(request.path_info).url_name
print(1)
if userID != 0:
print(2)
user = msignup.objects.filter(id=userID).first()
return user
print(3)
return HttpResponseRedirect(reverse('login') + "?next=
{}".format(next))
I tried to test this function with below view when user is loged out and request has no mainSession :
def email_activation(request):
user = is_login(request)
print(4)
email = user.email
return render(request, 'account/emailActivation.html',{'email':
email})
and in response I got this :
'HttpResponseRedirect' object has no attribute 'email'
and the response for prints that I had made is :
1
3
4
why after 3 redirect does not happens ?what am I doing wrong?
First of all. Django has a few ways to do this built-in. I strongly recomend you to use something that's already made. The login_required decorator would work great for your use case.
https://docs.djangoproject.com/en/1.11/topics/auth/default/#django.contrib.auth.decorators.login_required
Now, if what you're doing is an experiment. The problem that you have is that you are returning the response Redirect object on is_login. What you could to do to make this work (i again recommend you to not go with this route), is make another function that redirects to the login page, and have the is_login function just return True or False if the user is login or not.
Then you will be able to do something like:
if not is_login(request):
return redirectToSigninPage(request)

Code to run in all views in a views.py file

What would be the best way of putting a bit of code to run for all views in a views.py file?
I come from a PHP background and I normally put this in the constructor/index bit so that it always ran whatever page is being requested. It has to be specific for that views.py file though, I want to check that the user has access to 'this app/module' and want to avoid having to use decorators on all views if possible?
TL;DR
You should check about middlewares. It allows to execute some code before the view execution, the template rendering and other stuff.
Some words about middlewares
You can represent middlewares in your head like this:
As you can see, the request (orange arrow) go through every middleware before executing the view and then can hitting every middleware after (if you want to do something before the template processing for example).
Using Django 1.10
Arcitecture of middlewares have changed in Django 1.10, and are now represented by simple function. For example, here's a counter of visits for each page:
def simple_middleware(get_response):
# One-time configuration and initialization.
def middleware(request):
try:
p = Page.objects.get(url=request.path)
p.nb_visits += 1
p.save()
except Page.DoesNotExist:
Page(url=request.path).save()
response = get_response(request)
if p:
response.content += "This page has been seen {0} times.".format(p.nb_visits)
return response
return middleware
And voilĂ .
Using Django
Here's an example of middleware, which would update a counter for each visit of a page (admit that a Page Model exists with two field : url and nb_visits)
class StatsMiddleware(object):
def process_view(self, request, view_func, view_args, view_kwargs):
try:
p = Page.objects.get(url=request.path)
p.nb_visits += 1
p.save()
except Page.DoesNotExist:
Page(url=request.path).save()
def process_response(self, request, response):
if response.status_code == 200:
p = Page.objects.get(url=request.path)
# Let's say we add our info after the html response (dirty, yeah I know)
response.content += u"This page has been seen {0} times.".format(p.nb_visits)
return response
Hopes this will help you :)
Middleware is the solution but keep in mind the the order to define the middleware in the settings.py matters.

Django - Ajax registration

I am trying to allow registration (using this django-registration register view) to one of my applications from a modal dialog.
Since this form is in a modal box, I'd like to get an json reponse on success (instead of the default redirection)
How can I use this view (django-registration register) to manage the registration and send back a json response on success ?
I know how to make ajax/json responses, the question is how to use the django-registration view without the redirection behavior or wrap it into an other view to manage the response.
First you need to change the urls.py to wrap the existing view with another functionality. To do that you have to create a new backend package in backends folder and change urls.py there while keeping everything else intact, or you could just go ahead and modify the existing urls.py in the backend package.
I have not tested this, but it should work.
Point url to the new view:
# urls.py
url(r'^register/$', register_wrap,
{'backend': 'registration.backends.default.DefaultBackend'},
name='registration_register'),
# your new view that wraps the existing one
def register_wrap(request, *args, **kwargs):
# call the standard view here
response = register(request, *args, **kwargs)
# check if response is a redirect
if response.status_code == 302:
# this was redirection, send json response instead
else:
# just return as it is
return response
If you are going to need this for more views you can just create a decorator using this.
Why I would do is to check if request.is_ajax() in your normal after-successfull-registration-redirect view and return json response there.
You ask how you can use the existing view to manage the registration and send back a json response on success. Since the HttpResponseRedirect is pretty much hard coded in the view, you can't use the view as it is. Instead, either fork it, or write your own view and change the urls.py so that r'^register/$' directs to your new view.
As far as the json response is concerned, on success you can do something like this:
from django.utils import simplejson as json
def register_ajax(request):
...
return HttpResponse(json.dumps(dict(success=True, **dict_containing_data)))
Hope this helps