I use django-rest-framework first time. I use json format by default.
I need to send file for creating a new instance. This file has being saved in models.ImageField. However, I don't know which format this field requires for incoming file. I tried to send it in base64, but it isn't suitable.
TestCase for this problem:
class PersonTestCase(APITestCase):
def setUp(self):
self.c = APIClient()
def test_sign_up_with_valid_data(self):
with open('persons/test/bg.jpg', 'rb') as bg:
valid_registration_data = {
...,
'background': base64.b64encode(bg.read()).decode('utf-8'),
}
response = self.c.post('/persons/sign_up', valid_registration_data)
self.assertEqual(response.status_code, 201)
self.assertEqual(Person.objects.count(), 1)
self.assertEqual(Person.objects.get('username'), 'test_client74562984')
View:
class SignUpView(APIView):
"""
Create new user
"""
def post(self, request):
serializer = UserSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
response = Response(serializer.data, status=status.HTTP_201_CREATED)
return response
response = Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
return response
Related
Further to my earlier post yesterday: Post request to external Rest Service using Django - use returned json to update model
I have managed to post data to camunda using Django - request.post. Using the following script:
payload = "{\n \"businessKey\": \"SomeValue\",\n \"variables\": {\n \"Organisation_ID\": {\n \"value\": \"SOmeUUID\",\n \"type\": \"String\"\n },\n \"UserID\": {\n \"value\":\"Some User ID\",\n \"type\": \"String\"\n }\n }\n}"
However when I start to use variables from the form and format my payload using
class StartProcessView(View):
template_name = 'startdeliveryphase.html'
def get(self,request, *args, **kwargs):
form = IntStartDeliveryPhase
return render(request, self.template_name,{'form':form})
def post(self,request, *args, **kwargs):
form = IntStartDeliveryPhase(request.POST or None)
if form.is_valid():
data = form.cleaned_data
OrganisationID = data['Form_Field_OrganisationID']
UserID = data['Form_Field_User_ID']
BusinessKey = data['Form_Field_Business_Key']
url = "http://localhost:8080/engine-rest/process-definition/key/Process_B_PerProject/start"
payload = {"businessKey":BusinessKey,"variables":[{"Organisation":[{"value":OrganisationID, "type":"String"}]},[{"Startedby":[{"value":UserID,"type":"String"}]}]]}
headers = {
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data = payload)
#print(repsonse.errors)
print(response.text.encode('utf8'))
return render(request)
else:
return render(request,self.template_name,{'form':form})
I get an error from the camunda engine:-
b'{"type":"JsonParseException","message":"Unrecognized token \'businessKey\': was expecting (\'true\', \'false\' or \'null\')\\n at [Source: (org.camunda.bpm.engine.rest.filter.EmptyBodyFilter$1$1); line: 1, column: 13]"}'
the local vars shows the following:
▼ Local vars
Variable Value
BusinessKey
'1qaz'
OrganisationID
<Organisation: Some Local Authoristy>
UserID
<Actor_User: me#me.com>
args
()
data
{'Form_Field_Business_Key': '1qaz',
'Form_Field_CamundaInstanceID': 'sss',
'Form_Field_Camunda_HRef': 'ss',
'Form_Field_Camunda_TenantID': '22',
'Form_Field_DateCreated': datetime.datetime(2020, 4, 23, 19, 22, 30, tzinfo=<StaticTzInfo 'GMT'>),
'Form_Field_OrganisationID': <Organisation: Some Local Authoristy>,
'Form_Field_User_ID': <Actor_User: me#me.com>}
form
<IntStartDeliveryPhase bound=True, valid=True, fields=(Form_Field_OrganisationID;Form_Field_DateCreated;Form_Field_CamundaInstanceID;Form_Field_Camunda_HRef;Form_Field_Camunda_TenantID;Form_Field_User_ID;Form_Field_Business_Key)>
headers
{'Content-Type': 'application/json'}
kwargs
{}
payload
{'businessKey': '1qaz',
'variables': [{'Organisation': [{'type': 'String',
'value': <Organisation: Some Local Authoristy>}]},
[{'Startedby': [{'type': 'String',
'value': <Actor_User: me#me.com>}]}]]}
request
<WSGIRequest: POST '/bimProcess/'>
response
<Response [400]>
self
<bimProcess.views.StartProcessView object at 0x055B7898>
url
'http://localhost:8080/engine-rest/process-definition/key/Process_B_PerProject/start'
How do I get the correct format as required by camunda into which I can insert my variables with the required double quotes
EDIT Yay - I have finally got the correct sequence!!!!
def post(self,request, *args, **kwargs):
form = IntStartDeliveryPhase(request.POST or None)
if form.is_valid():
data = form.cleaned_data
OrganisationID = str(data['Form_Field_OrganisationID'])
UserID = str(data['Form_Field_User_ID'])
BusinessKey = data['Form_Field_Business_Key']
url = "http://localhost:8080/engine-rest/process-definition/key/Process_B_PerProject/start"
payload = {"businessKey":BusinessKey,"variables":{"Organisation":{"value":OrganisationID, "type":"String"},"Startedby":{"value":UserID,"type":"String"}}}
headers = {
'Content-Type': 'application/json'
}
payload2 = json.dumps(payload)
print (payload2)
response = requests.request("POST", url, headers=headers, data=payload2)
#print(repsonse.errors)
print(response.text.encode('utf8'))
return render(request)
else:
return render(request,self.template_name,{'form':form})
Now for the next questions:
1) I get a response from Camunda as a 200: the payload back from the post request needs to go back into the form data where it can then be saved without user interruption.
2)I am doing a post self on this form - what is the best way of achieving the sequence flow? should I do a redirect and pass the data through or is there a more efficient way? Also is there a better way to achieve the view.py than I have posted which is more efficient?
def post(self,request, *args, **kwargs):
form = IntStartDeliveryPhase(request.POST or None)
if form.is_valid():
data = form.cleaned_data
OrganisationID = str(data['Form_Field_OrganisationID'])
UserID = str(data['Form_Field_User_ID'])
BusinessKey = data['Form_Field_Business_Key']
url = "http://localhost:8080/engine-rest/process-definition/key/Process_B_PerProject/start"
payload = {"businessKey":BusinessKey,"variables":{"Organisation":{"value":OrganisationID, "type":"String"},"Startedby":{"value":UserID,"type":"String"}}}
headers = {
'Content-Type': 'application/json'
}
payload2 = json.dumps(payload)
print (payload2)
response = requests.request("POST", url, headers=headers, data=payload2)
#print(repsonse.errors)
print(response.text.encode('utf8'))
return render(request)
else:
return render(request,self.template_name,{'form':form})
I'm using Django and Python 3.7. I'm having trouble returning JSON from one of my views. I have this view code ...
def get_hints(request):
article_id = request.GET.get('article_id', None)
article = Article.objects.get(pk=article_id)
s = ArticlesService()
objects = s.get_hints(article)
data = ArticleSerializer(objects, many=True).data
print("data: ", data)
return HttpResponse(data, content_type="application/json")
The service method referenced returns the following data ...
def get_hints(self, article):
...
sorted_articles_map = OrderedDict(sorted(rank_map.items(), key=operator.itemgetter(1), reverse=True))
return list(sorted_articles_map.keys())
The data returned from the serializer looks like this, definitely not json ...
[OrderedDict([('id', 10777935), ('created_on_ms', 1577985486000.0), ('label', 'World'), ('title', "Outrage and Disgust After 'Serial Killer' ...,
How do I render proper JSON?
Edit: Adding Article serializer ...
class ArticleSerializer(serializers.ModelSerializer):
class Meta:
model = Article
fields = ['id', 'created_on_ms', 'label', 'title', 'mobile_path', 'path', 'url', 'is_media', 'checked_for_dup', 'original_path', 'is_spiked']
Option 1
Use the #api_view()--(drf doc) decorator of DRF along with Response--(drf doc) class
from rest_framework.decorators import api_view
from rest_framework.response import Response
#api_view(['GET'])
def get_hints(request):
article_id = request.GET.get('article_id', None)
article = Article.objects.get(pk=article_id)
s = ArticlesService()
objects = s.get_hints(article)
data = ArticleSerializer(objects, many=True).data
return Response(data)
Option 2
You will get similar response by using JsonResponse--(django doc)
from django.http.response import JsonResponse
def get_hints(request):
article_id = request.GET.get('article_id', None)
article = Article.objects.get(pk=article_id)
s = ArticlesService()
objects = s.get_hints(article)
data = ArticleSerializer(objects, many=True).data
return JsonResponse(data, safe=False)
I have a model Domain:
class Domain(models.Model):
name = models.CharField(max_length=50)
def __str__(self):
return self.name
And a corresponding serializer:
class DomainSerializer(serializers.ModelSerializer):
class Meta:
model = Domain
fields = ('name',)
I'm trying to serialize a queryset in a view like this:
def getDomains(request):
domains = Domain.objects.filter(name__startswith=request.GET['name_startsWith'])
data = DomainSerializer(domains, many=True)
print(data.data)
return HttpResponse(data.data)
This is not working correctly, and data.data is :
[OrderedDict([('name', 'Math')])]
I would like to have a JSON object, something like:
{'name': 'Math'}.
Try using JsonResponse to return the data:
from django.http import JsonResponse
.....
return JsonResponse(data.data)
I am trying to Extract JSON data from URL with parameters to it and code is as follows:
import json
from flask import Flask, render_template, request, jsonify
import requests
app = Flask(__name__)
import urllib2
#app.route("/",methods=['GET','POST'])
def home():
if request.method == 'POST':
#user inputs
valueone= request.form.get('first')
valueTwo = request.form.get('second')
valueThree = request.form.get('third')
#api call
data = {"perfid" : {0}, "section" : {"hostname" : {1}, "iteration" : {2}, "sectionname" : "sysstat_M"}}
req = urllib2.Request('http://api-latx-dev.corp.netapp.com/ws/spm/spm-general', json.dumps(data))
response = urllib2.urlopen(req)
the_page = response.read()
url=response.getcode()
returnData = {}
if url.status_code == 200:
returnData["status"] = "SUCCESS"
returnData["result"] = the_page
return jsonify(returnData)
else:
returnData["status"] = "ERROR"
return jsonify(returnData)
#jsonify(response.json())
return render_template('index.html')
I need to fetch data But getcode() gives int which is not working with "if url.status_code == 200".Can anyone please suggest how to deal with it.
Now I return a JSON file with the model fields and their values. I want to add some extra fields to the JSON that are not present in the model (I want to add a new field that specifies if an user can modify or not the diagnostic based on the permissions of the view). How I can do this?
models.py
class Diagnostic(models.Model):
Center = models.TextField(blank=True)
Author = models.TextField(blank=True)
Email = models.EmailField(blank=True)
Date = models.DateField(null = True, blank=True)
views.py
class DiagnosticViewSet(viewset.ModelViewSet):
model = Diagnostic
permission_classes = [GroupPermission]
serializers.py
class DiagnosticSerializer(serializers.ModelSerializer):
class Meta:
model = Diagnostic
Add this to your views
def list(self, request, *args, **kwargs):
response = super(Classname, self).list(request, *args, **kwargs)
try:
response.data['permission'] = 'give your permission'
except:
pass
return response
You add them to the serializer.
class DiagnosticSerializer(serializers.ModelSerializer):
auth_status = serializers.SerializerMethodField('get_auth_status')
class Meta:
model = Diagnostic
def get_auth_status(self, obj):
if obj.has_auth():
return True
return False
You have to use following code for the url localhost/diagnostics/1
from rest_framework.response import Response
def retrieve(self, request, *args, **kwargs):
self.object = self.get_object()
serializer = self.get_serializer(self.object)
data = serializer.data
data['permission'] = 'give your permission'
return Response(data)