how receive http post in django - django

send http post
import requests
payload = [{'name': 'pippo', 'age':'7'}, {'name':'luca', 'age':'12'}]
r = requests.post("http://127.0.0.1:8000", data=payload)
print(r.url)
Receive Http post in django
from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt
from home.models import Post
#csrf_exempt
def home(request):
all_post = Post.objects.all()
context = {'request_method': request.method}
if request.method == 'POST':
context['request_payload'] = request.POST.dict()
post_data = dict(request.POST)
print(post_data)
if request.method == 'GET':
context['request_payload'] = request.GET.dict()
return render(request, 'main/index.html', context, {'all_post':all_post})
in print(post_data) i not see [{'name': 'pippo', 'age':'7'}, {'name':'luca', 'age':'12'}]
why? where is my error?

you should give a name to the data you want to post via requests. like this:
payload = {'data': [{'name': 'pippo', 'age':'7'}, {'name':'luca', 'age':'12'}]}
and when you want to get data do it like this:
post_data = request.POST['data']

Related

program connecting through postman is not working( get the data through POST then filter it accordingly)

from django.core.mail.backends import console
from home.models import Flights
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
#csrf_exempt
def status(request):
if request.method == 'POST':
value1 = request.POST.get('status')
if (value1 == "Arrival"):
arr = list(Flights.objects.filter(status="Arrival").values())
return JsonResponse(arr, safe=False)
elif (value1 == "Departure"):
dep = list(Flights.objects.filter(status="Departure").values())
return JsonResponse(dep, safe=False)
else:
results = list(Flights.objects.values())
return JsonResponse(results, safe=False)
return
i tried to give json input through postman then the loop is not executing is it the problem with code or jason data given in postman?

How do I use a POST method to communicate with an external API in Django?

I received help from my instructor to figure out the GET command. I am struggling with the POST command.
-View-
from django.shortcuts import render
from django.shortcuts import redirect
from django.contrib import messages
import json
import requests
from ast import literal_eval
from django.shortcuts import redirect
from rest_framework.views import APIView
from rest_framework.response import Response
def add_question(request):
if request.method == 'POST':
url = 'http://localhost:3000/questions/'
payload = {'content':request.POST.get("content"), 'category':request.POST.get("category")}
res = requests.post(url, data = (payload))
print(res)
return Response(res.json())
Part of my problem is that most of the previously published advice on this topic is over 3 years old. I don't think the 'rest_framework' module is used much for this purpose anymore. It's hard to tell.
Right now the error I am getting is: "raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) "POST /add_question HTTP/1.1" 500 92794"
The GET method that worked for me was this:
def home(request):
if request.method == 'GET':
print('home')
api_request = requests.get("http://localhost:3000/questions/")#.json()
try:
print( 'api_request='+str(api_request))
q = literal_eval(api_request.content.decode('utf8'))
print('q=', q, type(q))
print( q['data'])
json_obj = json.dumps(q['data'])
print('json_obj=', json_obj, type(json_obj))
#api = json.loads(api_request.content)
api = json.loads(json_obj)
except Exception as e:
print( 'Exception e='+str(e))
api = "Error..."
else:
if request.method == 'POST':
post_request = requests.post("http://localhost:3000/questions/")
print(post_request)
return render(request, 'frontend/home.html', {'api': api})
The API I am using is one I created in Node.js. The error I am getting from Node when I attempt the post is: "ReferenceError: question is not defined
at addQuestion (file:///C:/nodepract/Project05/api/routes/questions.js:60:47)"
I changed the view to the following.
def add_question(request):
if request.method == 'POST':
url = 'http://localhost:3000/questions/'
data = json.dumps(request.POST)
res = requests.post(url, data)
print("res.text = " + res.text)
return Response(res.json())
Currently getting following error.
"ReferenceError: question is not defined"
The exception is thrown because the data that you receive from the external API http://localhost:3000/questions/ is not JSON data.
To debug the response, print the res.text before res.json call.

Set Django's RequestFactory() method to equal 'POST'

Example view function:
def example_view(request):
if request.method == "POST":
print(request.session['Key'])
return HttpResponse("Success")
Test case to test view:
from django.contrib.sessions.backends.db import SessionStore
from django.test import RequestFactory, TestCase
from website.views import example_view
class ExampleTestCase(TestCase):
def test_example(self):
# Create request and session
request = RequestFactory()
request.session = SessionStore()
request.session['Key'] = "Value"
response = example_view(request)
self.assertEquals(response.status_code, 200)
urls.py file in case anyone asks for it:
urlpatterns = [
path('example', views.example_view, name="example_view"),
]
Error Response:
AttributeError: 'RequestFactory' object has no attribute 'method'
Without:
if request.method == 'POST':
this works as expected.
How do I set the request.method equal to post?
RequestFactory gives you a factory, not a request, to get the request you must call the factory as you'd do with the Django testing client:
factory = RequestFactory()
request = factory.post('/your/view/url')
response = example_view(request)

Rest api in django POST method

views.py
from django.shortcuts import render, HttpResponse, get_object_or_404
from django.http import JsonResponse
from .models import Locker
from .serializers import LockerSerializer
from rest_framework.response import Response
from rest_framework import status
from rest_framework.views import APIView
from django.core import serializers
def locker_data_response(request):
if request.method == 'GET':
locker_mac_address = request.GET.get('locker_mac_address') # this will return None if not found
locker_information = get_object_or_404(Locker, locker_mac_address = locker_mac_address)
print(locker_information)
locker_information_serialize = LockerSerializer(locker_information)
print(locker_information_serialize)
return JsonResponse(locker_information_serialize.data)
elif request.method == 'POST':
locker_all_information_in_json = serializers.get_deserializer(request.POST())
print(locker_all_information_in_json)
json data
{
"id": 1,
"locker_name": "H15_c6d730",
"locker_mac_address": "CE:B2:FE:30:D7:C6",
"locker_rssi": -78,
"locker_protocol_type": "5",
"locker_protocol_version": "3",
"locker_scene": "2",
"locker_group_id": "0",
"locker_org_id": "0",
"locker_type": 5,
"locker_is_touch": true,
"locker_is_setting_mode": false,
"locker_is_wrist_band": false,
"locker_is_unlock": false,
"locker_tx_power_level": "-65",
"locker_battery_capacity": "57",
"locker_date": 1518500996721,
"locker_device": "CE:B2:FE:30:D7:C6",
"locker_scan_record": "terterwer"
}
I am trying to send the json in this format from mobile device to my server.I check the get method, it works perfectly. But how can i post this json in my server and how can i get the json data in my server side?
Change your views to something like this,
def locker_data_response(request):
# ----
# ----
# ----
if request.method == 'POST':
post_data = request.data # your post data will be here
locker_all_information_in_json = serializers.get_deserializer(post_data)
# do stuff with post data
#return json_data
request.data holds the POST data to the view

django-rest testing views with custom authentication

I try to test view that has custom authentication, mainly because the main auth is based on external login-logout system, utilizing Redis as db for storing sessions.
Auth class is checking session id from the request, whether it is the same as in Redis - if yes, succeed.
My custom authentication.py looks like:
from django.utils.six import BytesIO
from rest_framework import authentication
from rest_framework import exceptions
from rest_framework.parsers import JSONParser
import redis
class RedisAuthentication(authentication.BaseAuthentication):
def authenticate(self, request):
print(request.META)
token = request.META['HTTP_X_AUTH_TOKEN']
redis_host = "REDIS_IP_ADRESS"
redis_db = redis.StrictRedis(host=redis_host)
user_data = redis_db.get("user_feature:{}".format(token))
if user_data is None:
raise exceptions.AuthenticationFailed('No such user or session expired')
try:
stream = BytesIO(user_data) # Decode byte type
data = JSONParser(stream) # Parse bytes class and return dict
current_user_id = data['currentUserId']
request.session['user_id'] = current_user_id
except Exception as e:
print(e)
return (user_data, None)
and my views.py looks like:
#api_view(['GET', 'POST'])
#authentication_classes((RedisAuthentication, ))
def task_list(request):
if request.method == 'GET':
paginator = PageNumberPagination()
task_list = Task.objects.all()
result_page = paginator.paginate_queryset(task_list, request)
serializer = TaskSerializer(result_page, many=True)
return paginator.get_paginated_response(serializer.data)
elif request.method == 'POST':
serializer = PostTaskSerializer(data=request.data)
if serializer.is_valid():
user_id = request.session.get('user_id')
serializer.save(owner_id=user_id)
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Manual tests pass, but my current pytests failed after adding authentication.py, and have no clue how I can fix it properly - tried with forcing auth, but no succeed.
I'm thinking that one of solution will be use fakeredis for simulate real redis. Question is, how that kind of test should looks like?
Example of test you could find here:
#pytest.mark.webtest
class TestListView(TestCase):
def setUp(self):
self.client = APIClient()
def test_view_url_accessible_by_name(self):
response = self.client.get(
reverse('task_list')
)
assert response.status_code == status.HTTP_200_OK
#pytest.mark.webtest
class TestCreateTask(TestCase):
def setUp(self):
self.client = APIClient()
self.user = User.objects.create_user(username='admin', email='xx', password='xx')
def test_create(self):
data = {some_data}
self.client.login(username='xx', password='xx')
response = self.client.post(
reverse('task_list'),
data,
format='json')
assert response.status_code == status.HTTP_201_CREATED
self.client.logout()
Thanks in advance for any help!
I managed to mock whole redis auth using mock.patch decorator - https://docs.python.org/3.5/library/unittest.mock-examples.html#patch-decorators.
When you put import patch to mock.patch decorator, do not insert absolute module path where redis code is stored, but insert the path where redis code was imported as a module and used.
My test looks like that now:
#mock.patch('api.views.RedisAuthentication.authenticate')
def test_view_url_accessible_by_name(self, mock_redis_auth):
data = {"foo": 1, "currentUserId": 2, "bar": 3}
mock_redis_auth.return_value = (data, None)
response = self.client.get(
reverse('task_list'),
HTTP_X_AUTH_TOKEN='foo'
)
assert response.status_code == status.HTTP_200_OK