Rest api in django POST method - django

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

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?

drf-yasg: How to hide Django rest Framework schema?

I use drf_yasg swagger for my Django API.
I would like to know how to easily disable the schema and model.
screenshot
here is my code:
from .models import Articles
from .serializers import ArticlesSerializer
from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework import status
from rest_framework.authentication import SessionAuthentication,TokenAuthentication, BasicAuthentication
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
from rest_framework.parsers import JSONParser
from django.utils.decorators import method_decorator
from django.contrib.auth import authenticate, login, logout
from rest_framework.decorators import api_view
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi
#swagger_auto_schema(methods=['get'], operation_description="description", manual_parameters=[
openapi.Parameter('category', openapi.IN_QUERY, "category1, category2, category3", type=openapi.TYPE_STRING),
openapi.Parameter('name', openapi.IN_QUERY, "full name", type=openapi.TYPE_STRING),
], responses={
200: openapi.Response('Response', ArticlesSerializer),
}, tags=['Articles'])
# desactivate POST methode on swagger
#swagger_auto_schema(method='POST', auto_schema=None)
#api_view(['GET','POST'])
def articles(request):
"""
List all articles.
"""
if request.user.is_authenticated:
if request.method == 'GET':
articles = Articles.objects.all()
serializer = ArticlesSerializer(Articles, many=True)
return JsonResponse(serializer.data, safe=False)
elif request.method == 'POST':
data = JSONParser().parse(request)
serializer = ArticlesSerializer(data=data)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data, status=201)
return JsonResponse(serializer.errors, status=400)
return JsonResponse({"status":"403", "message":"User not authenticated"})
If i add this
class UserList(APIView):
swagger_schema = None
i got error:
AssertionError: `method` or `methods` can only be specified on #action or #api_view views
Code Edited:
the articles function is pretty simple nothing related to the API, only Python code.
Here the views Class is also pretty simple.
Class Views:
from django.db import models
class Articles(models.Model):
STATUS = (
(1, 'PENDING'),
(2, 'COMPLETED'),
(3, 'DECLINED'),
(0, 'BANNED'),
)
name = models.CharField(max_length=100)
...
status = models.PositiveSmallIntegerField(
choices = STATUS,
default = 1,
)
I only have half of the answer, to disable Models I added this to my setting.py
SWAGGER_SETTINGS = {
'DEFAULT_FIELD_INSPECTORS': [
'drf_yasg.inspectors.CamelCaseJSONFilter',
'drf_yasg.inspectors.InlineSerializerInspector',
'drf_yasg.inspectors.RelatedFieldInspector',
'drf_yasg.inspectors.ChoiceFieldInspector',
'drf_yasg.inspectors.FileFieldInspector',
'drf_yasg.inspectors.DictFieldInspector',
'drf_yasg.inspectors.SimpleFieldInspector',
'drf_yasg.inspectors.StringDefaultFieldInspector',
],
}
Credit goes to this guys, and here is the documentation for more details.
I finally figured it out.
I just had to overwrite the responses parameter with either plain text, markdown or html.
#swagger_auto_schema(methods=['get'], operation_description="Get article information ", manual_parameters=[
openapi.Parameter('id', openapi.IN_QUERY, "Article Id", type=openapi.TYPE_STRING),
], responses={ 200: '**Example:** \
<div class="highlight-code"><pre>{ <br>\
"category": "string", <br>\
"image": "string",<br>\
"link": "string",<br>\
"birth_date": "string",<br>\
}</pre></div>'},
tags=['Get Articles'])
To have the same css effect (background black) you can add this custom CSS in the file ...\site-packages\drf_yasg\static\drf-yasg\style.css
.swagger-ui .markdown .highlight-code pre{
color: #fff;
font-weight: 400;
white-space: pre-wrap;
background: #41444e;
padding: 15px;
}

how receive http post in 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']

parameter passing in django

I am trying to use REST API in django for retrieve some data in json format.
When i hit this url:
http://192.168.2.87:8000/locker/123/
It gives me output like this (from Database)
{"id": 1, "locker_id": 123, "locker_user_name": "taimur"}
But if i want to get the output by passing the parameters like this
http://192.168.2.87:8000/locker/?locker_id=123&locker_user_name=taimur&id=1
views.py
from postman, How can i do this??
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
def locker_data_response(request, locker_id):
if request.method == 'GET':
locker_information = get_object_or_404(Locker, locker_id = locker_id)
print(locker_information)
locker_information_serialize = LockerSerializer(locker_information)
print(locker_information_serialize)
return JsonResponse(locker_information_serialize.data)
urls.py
from django.urls import path, re_path
from . import views
urlpatterns = [
re_path('(?P<locker_id>[0-9]+)/$', views.locker_data_response, name='locker_data_response'),
]
You get them from the request object:
def locker_data_response(request):
if request.method == 'GET':
locker_id = request.data.get('locker_id') # this will return None if not found
locker_user_name = request.data.get('locker_user_name')
locker_information = get_object_or_404(Locker, locker_id=locker_id)
print(locker_information)
locker_information_serialize = LockerSerializer(locker_information)
print(locker_information_serialize)
return JsonResponse(locker_information_serialize.data)
And the url will change to:
locker/$
[EDIT: Sorry, if you are using drf you should use data rather than GET]
[EDIT 2: If you want to use it like this, you will also need to change the url and signature of the view]
[EDIT 3: Added the code in the correct place in view]
If your url is something like domain/search/?q=haha, Then you would use request.GET.get('q', '').
q is the parameter you want, And '' is the default value if q isn't found.
If you are instead just configuring your URLconf, Then your captures from the regex are passed to the function as arguments (or named arguments).
Such as:
(r'^user/(?P<username>\w{0,50})/$', views.profile_page,),
Then in your views.py you would have
def profile_page(request, username):
# Rest of the method

Django testing stored session data in tests

I have a view as such:
def ProjectInfo(request):
if request.method == 'POST':
form = ProjectInfoForm(request.POST)
if form.is_valid():
# if form is valid, iterate cleaned form data
# and save data to session
for k, v in form.cleaned_data.iteritems():
request.session[k] = v
return HttpResponseRedirect('/next/')
else:
...
else:
...
And in my tests:
from django.test import TestCase, Client
from django.core.urlresolvers import reverse
from tool.models import Module, Model
from django.contrib.sessions.models import Session
def test_project_info_form_post_submission(self):
"""
Test if project info form can be submitted via post.
"""
# set up our POST data
post_data = {
'zipcode': '90210',
'module': self.module1.name,
'model': self.model1.name,
'orientation': 1,
'tilt': 1,
'rails_direction': 1,
}
...
self.assertEqual(response.status_code, 302)
# test if 'zipcode' in session is equal to posted value.
So, where the last comment is in my test, I want to test if a specific value is in the session dict and that the key:value pairing is correct. How do I go about this? Can I use request.session?
Any help much appreciated.
According to the docs:
from django.test import TestCase
class SimpleTest(TestCase):
def test_details(self):
# Issue a GET request.
self.client.get('/customer/details/')
session = self.client.session
self.assertEqual(session["somekey"], "test")