how to send send the data using python django? - python

How to send the json data using post request in django python.
I have a code for get the data and I don't use any html file.
class employeeList(APIView):
def get(self, request):
employee1 = employees.objects.all()
serializer = employeeSerializer(employee1, many=True)
return Response(serializer.data)
def post(self,request):
pass
can you please help for post request.Now I want to create post function to send the data

You can use this basically,
def post(self, request):
serializer = employeeSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response({'message':'Data davet succesfully'})

You can simply dump query set into Json format like:
def post(self, request):
data = list(employees.objects.values())
return JsonResponse(data, safe=False)
# or
return JsonResponse({'data': data})

Related

DRF: how do I call a class inside another class method?

I have two separate methods:
to load and validate a csv file FileUploadView(APIView) [PUT]
to add new objects to the database based on their uploaded file data
CsvToDatabase [POST]
file upload
class FileUploadView(APIView):
parser_classes = (MultiPartParser, FormParser)
permission_classes = (permissions.AllowAny,)
def put(self, request, format=None):
if 'file' not in request.data:
raise ParseError("Empty content")
f = request.data['file']
filename = f.name
if filename.endswith('.csv'):
file = default_storage.save(filename, f)
r = csv_file_parser(file)
status = 204
else:
status = 406
r = "File format error"
return Response(r, status=status)
create instances
class CsvToDatabase(APIView):
def post(self, request, format=None):
r_data = request.data
...
#some logic
...
serializer = VendorsCsvSerializer(data=data)
try:
serializer.is_valid(raise_exception=True)
serializer.save()
except ValidationError:
return Response({"errors": (serializer.errors,)},
status=status.HTTP_400_BAD_REQUEST)
else:
return Response(request.data, status=status.HTTP_200_OK)
urls.py
urlpatterns = [
path('csv_upload/', FileUploadView.as_view(), name='csv_upload'),
path('from_csv_create/', CsvToDatabase.as_view(), name='csv_vendor_create'),]
At the moment I am simply passing manually to Postman the result of the PUT method of FileUploadView class (Response(r, status=status) get me json ) to POST method of CsvToDatabase class.
Of course, this option is not suitable for a working application. I would like to know if there is a way to call the POST method automatically inside FileUploadView class after the .csv file is processed and json is received.
I know I can transfer a POST method to a class FileUploadView and call the self.POST method inside the PUT. But combining functionality will make testing much more complicated, so I want to use different url. If that's possible, of course.

Why does context={'request': self.request} need in serializer?

Today I dig into django-rest-auth package a bit. And I have no idea what context={'request': self.request} for in get_response and post function.
They say context parameter is for including extra context to serializer. But below the codes, it seems not necessary to put context parameter. Is there something I have missed?
context: http://www.django-rest-framework.org/api-guide/serializers/
django-rest-auth : https://github.com/Tivix/django-rest-auth/blob/master/rest_auth/views.py
def get_response(self):
serializer_class = self.get_response_serializer()
if getattr(settings, 'REST_USE_JWT', False):
data = {
'user': self.user,
'token': self.token
}
serializer = serializer_class(instance=data,
context={'request': self.request})
else:
serializer = serializer_class(instance=self.token,
context={'request': self.request})
return Response(serializer.data, status=status.HTTP_200_OK)
def post(self, request, *args, **kwargs):
self.request = request
self.serializer = self.get_serializer(data=self.request.data,
context={'request': request})
self.serializer.is_valid(raise_exception=True)
self.login()
return self.get_response()
Sometimes you need request's data inside serializer method. For this case you can provide request to serializer's context. For example if you look into PasswordResetSerializer you'll see in save method use_https option which calculated based on the request passed with context argument:
def save(self):
request = self.context.get('request')
# Set some values to trigger the send_email method.
opts = {
'use_https': request.is_secure(),
'from_email': getattr(settings, 'DEFAULT_FROM_EMAIL'),
'request': request,
}
Also you can check if user is authenticated or not and depends on it return one data or another on serializer level.

Django rest_framework request post data to remote server using class views and modelviewset

I am new to Django and rest_frameworks. A Django app that is using REST_Framework which looks like below
The goal is that when a a POST is called, the form data/json is sent to remote server url, using "request.post". Currently the code gives no errors, however the data is not posted to the remote server url.
My sample code for the class view is below:
class SnippetViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows containers to be viewed or edited.
"""
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
#detail_route(methods=['post'])
def snippet_detail(self, request):
Snippet = self.get_object()
serializer = SnippetSerializer(data=request.data)
if serializer.is_valid():
headers= {"Content-type":"application/json", "encoding":"utf-8"}
url = "http://198.0.10.1:5000/create?name=rstudio"
r = requests.post(url, data=json.dumps(serializer), headers =headers)
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors,
status=status.HTTP_400_BAD_REQUEST)
Add .data to the serializer in json.dumps.
r = requests.post(url, data=json.dumps(serializer.data), headers=headers)

How to delete an object using Django Rest Framework

I am trying to write an RESTful API for my event planning app using Django Rest Framework but I am having some trouble when using views that do not expect the GET HTTP method. I have read through the tutorial on the DRF site. From what I understand after reading through the tutorial and the class based view documentation on the Django site is that if there is a class based view like this (taken from the DRF tutorial)
class SnippetDetail(APIView):
"""
Retrieve, update or delete a snippet instance.
"""
def get_object(self, pk):
try:
return Snippet.objects.get(pk=pk)
except Snippet.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
snippet = self.get_object(pk)
serializer = SnippetSerializer(snippet)
return Response(serializer.data)
def put(self, request, pk, format=None):
snippet = self.get_object(pk)
serializer = SnippetSerializer(snippet, data=request.DATA)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk, format=None):
snippet = self.get_object(pk)
snippet.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
The different methods in the view correspond to the different HTTP Request methods. So if I have www.foo.com/bar it would do two different things based on what request method is sent to that address. So that means that I wouldn't have to specify anything else because the function that is executed is determined based on the method the URL is sent with. Is this correct?
I have this view which I tried to model after the example on the DRF site
class EventDetail(APIView):
"""
Retrieve, update or delete a event instance.
"""
def get_object(self, pk):
try:
return Event.objects.get(pk=pk)
except Event.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
event = self.get_object(pk)
serializer = EventSerializer(event)
return Response(serializer.data)
def post(self, request, format=None):
serializer = EventSerializer(data=request.DATA)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# def put(self, request, pk, format=None):
# event = self.get_object(pk)
# serializer = EventSerializer(event, data=request.DATA)
# if serializer.is_valid():
# serializer.save()
# return Response(serializer.data)
# return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk, format=None):
event = self.get_object(pk)
event.delete()
return Response(status=status.HTTP_204_NO_CONTENT
which maps to these URLs
urlpatterns = patterns('',
# Get event
url(r'^(?P<pk>\d+)/$', views.EventDetail.as_view(),
name='create_events'),
# list all events
url(r'^list/$', views.EventList.as_view(),
name='list_events'),
# url(r'^update$/(?P<pk>\d+)', #update event),
url(r'^create/$', views.EventDetail.as_view(),
name='create_events'),
# delete event
url(r'^delete$/(?P<pk>\d+)',
views.EventDetail.as_view(), name='delete_event'),
)
which I am trying to test using CURL with this command (like suggested here DELETE using CURL with encoded URL)
curl -X DELETE "http://127.0.0.1:8000/events/delete/1"
This will seem to do what it should:
[18/Oct/2014 22:41:27] "DELETE /events/delete/1 HTTP/1.1" 404 2707
But the actual record is not deleted from my database
Is there something here that I am forgetting to do to get these to get this to work properly?
You're being redundant. The HTTP method is already DELETE, so there's no /events/delete in the url. Try this:
curl -X DELETE "http://127.0.0.1:8000/events/1/"
By default, DRF's router creates detailed urls at /event/<pk> and you GET, PUT, POST and DELETE them to retrieve, update, create and delete respectively.
As mentioned by Kevin Stone, the pattern you're using isn't advisable, but if you want to use it, you'll need to fix the typo in your urls for the events/delete/ mapping.
# delete event
url(r'^delete$/(?P<pk>\d+)',
views.EventDetail.as_view(), name='delete_event'),
should be:
# delete event
url(r'^delete/(?P<pk>\d+)',
views.EventDetail.as_view(), name='delete_event'),

django : passing form data between views

I have a view :
class SomeView(FormView):
form_class = SomeForm
template_name = 'app/template.html'
def get(self, request, *args, **kwargs):
form = self.form_class
return render(request, self.template_name, {form:'form'})
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_Valid():
#do something here
return HttpResponseRedirect("Go somewhere from here after processing")
In the post I need to make an API call which takes data from this form. Instead of this though, I want to redirect user to another view, where he can view all the data from the form and say confirm
On submit of this confirm view I should actually make this API call.
How do I pass the form data to another view ? I can simply store the form data in a dict and pass it on from the URL, but that might expose some crucial data at the browser level.
Is there a safer way to do this ?
Thanks
Yes, there is a litle helper from django:
https://docs.djangoproject.com/en/1.5/ref/contrib/formtools/form-preview/

Categories