Django Rest Framework API POST receiving status code 200 instead 201 - python

I am new to Django and python. I have a website that already in production using docker. And the API URL is on: http://gmlews.com/api/data. When I want to test the API using postman, the GET method working fine, but for the POST method is returned response 200 OK not 201 created. Because of that, my data can't be saved in the API.
Here is my code for the API :
restapi/serializers.py:
from .models import Data,Node
from rest_framework import serializers
class DataSerializer(serializers.ModelSerializer):
class Meta:
model = Data
fields = '__all__'
class NodeSerializer(serializers.ModelSerializer):
class Meta :
model = Node
fields = '__all__'
restapi/views.py:
import json
from django.views.generic import View
from django.shortcuts import render
from rest_framework import routers, serializers, viewsets
from rest_framework.response import Response
from restapi.serializers import DataSerializer, NodeSerializer
from restapi.models import Data, Node
from django_filters.rest_framework import DjangoFilterBackend
from django.http import HttpResponse
from rest_framework.views import APIView
# Create your views here.
class DataViewSet(viewsets.ModelViewSet):
queryset = Data.objects.all()
serializer_class = DataSerializer
filter_backends = [DjangoFilterBackend]
filterset_fields = ['node_id']
class MapViewSet(viewsets.ModelViewSet):
queryset = Data.objects.filter(node_id=1).order_by('-id')[:1]
serializer_class = DataSerializer
class NodeViewSet(viewsets.ModelViewSet):
queryset = Node.objects.all()
serializer_class = NodeSerializer
urls.py:
from django.contrib import admin
from django.contrib.auth import views as auth_views
from django.urls import include, path
from restapi import views
""" for routers api root"""
from restapi.models import Data, Node
from rest_framework import routers
from restapi.views import DataViewSet, NodeViewSet, MapViewSet
router = routers.DefaultRouter()
router.register(r'data', DataViewSet, 'data')
router.register(r'node', NodeViewSet, 'node')
router.register(r'map', MapViewSet, 'map')
urlpatterns = [
path('admin/', admin.site.urls),
path(r'api/', include(router.urls)),
path(r'', include('rest_framework.urls', namespace='rest_framework')),
]
Can someone help me with this issue? I really don't have an idea why the POST method received status 200. I want it to received status 201 so my data can be saved. Thank you

Acessed your site and did a post. It returned a 201.
Follow is the evidence:
If you access you data, the item with id 15 was created by me, and the current response for that POST was a 201.

Related

Why my response data is not being shown in the postman and how do I see the request data in Django

views.py
from django.shortcuts import render
from rest_framework import viewsets
from django.http import HttpResponse
from .serializers import TodoSerializer
from .serializers import UserSerializer
from .models import Todo
from .models import User
class TodoView(viewsets.ModelViewSet):
serializer_class = TodoSerializer
queryset = Todo.objects.all()
def get_object(request):
return "Added";
class UserView(viewsets.ModelViewSet):
serializer_class = UserSerializer
queryset = User.objects.all()
def get_object(request):
print("request", request)
return "Registered";
class LoginView(viewsets.ModelViewSet):
#serializer_class = UserSerializer
#queryset = User.objects.all()
#print("queryset = ",queryset[len(queryset)-1].email_id)
#print("serializer_class = ",serializer_class)
def get_object(self,request):
return HttpResponse("request")
# Create your views here.
urls.py
from django.contrib import admin
from django.urls import path, include
from rest_framework import routers
from todo import views
router = routers.DefaultRouter()
router.register(r'users', views.UserView)
router.register(r'todos', views.TodoView)
router.register(r'login', views.LoginView)
print("In url file")
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include(router.urls)),
]
This is my views.py file and urls.py file.
I have a model created for user, with fields- email_id and password
CRUD operations are implemented automatically, so how do I validate data passed from the login form in frontend
Please tell me what's wrong in the code. I am not able to do the login part.

Error in Django Rest Framwork. 'str' object has no attribute 'pk'

I'm trying to get the output from a Stored Procedure which I have written in MS SQL server into Rest API. I have succeeded in getting the Output. But I have failed in appending the output to rest api. Please help....
Here is my serializers.py code:
class Get_Count_Serializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = ErRegisteredUsers
fields = ('__all__')
Here is my views.py code:
from django.db import connection
from .serializers import *
from .models import *
from rest_framework import viewsets
class Get_Count_Viewset(viewsets.ModelViewSet):
cursor = connection.cursor()
cursor.execute('EXEC [dbo].[ER_Get_Registration_Types_Count]')
results = cursor.fetchone()
#result = dict(results)
queryset = results
serializer_class = Get_Count_Serializer
This is my urls.py
from django.urls import include, path
from rest_framework import routers
from . import views
router = routers.DefaultRouter()
router.register('Get_Count', views.Get_Count_Viewset, basename='Get_Count')
# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
path('admin/', include(router.urls)),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
This is the error I'm getting,

how to make drf HyperlinkedModelSerializer elegantly work with app_name?

I am using drf in django project
# project/urls.py
from django.urls import include, path
urlpatterns = [
...
path('drf/', include('api.urls')),
...
]
in a dedicated app which I namespaced via app_name as following:
# api/urls.py
from django.urls import include, path
from rest_framework import routers
from . import views
app_name = 'drf'
router = routers.SimpleRouter()
router.register('segments', views.SegmentViewSet)
urlpatterns = [
path('', include(router.urls)),
]
# api/serializers.py
from rest_framework import serializers
from segment.models import Segment
class SegmentSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Segment
fields = ['id', 'url', 'name']
# api/views.py
from rest_framework import viewsets
from .serializers import SegmentSerializer
from segment.models import Segment
class SegmentViewSet(viewsets.ModelViewSet):
queryset = Segment.objects.all()
serializer_class = SegmentSerializer
calling endpoint /drf/segments/ results in the following error:
ImproperlyConfigured at /drf/segments/
Could not resolve URL for hyperlinked relationship using view name "segment-detail". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field.
Request Method: GET
Request URL: http://localhost:8000/drf/segments/
Django Version: 2.2.7
Python Executable: /Users/udos/.virtualenvs/ts/bin/python
Python Version: 3.6.4
.
.
.
to "fix" this, I have to add the following code to the serializer:
url = serializers.HyperlinkedIdentityField(
view_name='drf:segment-detail',
)
resulting in:
# api/serializers.py
from rest_framework import serializers
from segment.models import Segment
class SegmentSerializer(serializers.HyperlinkedModelSerializer):
url = serializers.HyperlinkedIdentityField(
view_name='drf:segment-detail',
)
class Meta:
model = Segment
fields = ['id', 'url', 'name']
I have to do this for all entities (which I would like to avoid).
is there a way to handle this without using the extra code? some magic method/attribute to call/set?

Unable to do PUT operation -DjangoRESTFramework

I am unable to do PUT operation in Django rest framework, I am able to GET, POST, DELETE operation.
This is the error
I have tried using #api_view but there also its not,
I mostly refer the djangorestframework website
Below is my code:
serializers.py
from rest_framework import serializers
from snippets.models import Snippet
#from django.contrib.auth.models import *
class SnippetSerializer(serializers.ModelSerializer):
class Meta:
model = Snippet
fields = ('id','title','code')
Models.py
from __future__ import unicode_literals
from django.db import models
# Create your models here.
class Snippet(models.Model):
created = models.DateTimeField(auto_now_add=True)
title = models.CharField(max_length=100, blank=True, default='')
code = models.CharField(max_length=100, blank=True, default='')
class Meta:
ordering = ('created',)
Views.py
from rest_framework import viewsets
from rest_framework.decorators import api_view
from snippets.serializers import SnippetSerializer
class SnippetViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows users to be viewed or edited.
"""
queryset = Snippet.objects.all().order_by('id')
serializer_class = SnippetSerializer
urls.py
rom django.conf.urls import url, include
from rest_framework import routers
from django.contrib import admin
from snippets import views
router = routers.DefaultRouter()
router.register(r'snippet', views.SnippetViewSet)
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^', include(router.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
]
Looking at the documentation of DefaultRouter, it looks like that PUT method can only be used with {basename}-detail type of URLs.
While you are using it directly on /snippet url where it is not allowed.

Using Django REST Framework API for data model with composite key

How do you use Django Rest Framework to create an API when the data model has a composite key consisting of two fields? Background: I am trying to make a REST api for a data model (sample data row below- first two entries make the composite key). I am able call upon my data with date field but am getting errors when I try to use the second string field to return a single record.
'2015-05-06','INTC','31.93','32.79','32.50','32.22','31737537'
I am trying to make the api url structure like so:
localhost/api/v1/yyyy-mm-dd/'char'
localhost/api/v1/2015-05-07/AAPL
serializers.py
from rest_framework import serializers
from .models import Stocksusa, Optionsusa
from rest_framework.reverse import reverse
class StocksUsaSerializer(serializers.HyperlinkedModelSerializer):
url = serializers.SerializerMethodField('get_stock_usa_url')
def get_stock_usa_url(self, obj):
values = [obj.Trade_Date, obj.Ticker]
composite_key_url = "http://0.0.0.0:9978/api/v1/stocksusa/{}/{}".format(*values)
return composite_key_url
class Meta:
model = Stocksusa
fields = ('Trade_Date', 'Ticker', 'PxMin', 'PxMax', 'PxOpen', 'PxClose', 'Volume', 'url')
views.py
from django.shortcuts import render
from rest_framework import authentication, permissions, viewsets, filters
from .models import Stocksusa
from .serializers import StocksUsaSerializer
from django.contrib.auth import get_user_model
User = get_user_model()
class DefaultsMixin(object):
authentication_classes = (
authentication.BasicAuthentication,
authentication.TokenAuthentication,
)
permission_classes = (
permissions.IsAuthenticated,
)
paginate_by = 25
paginate_by_param = 'page_size'
max_paginate_by = 100
filter_backends = (
filters.DjangoFilterBackend,
filters.SearchFilter,
filters.OrderingFilter,
)
class StocksUsaViewSet(DefaultsMixin, viewsets.ReadOnlyModelViewSet):
queryset = Stocksusa.objects.all()
serializer_class = StocksUsaSerializer
app/urls.py
from rest_framework.routers import DefaultRouter
from . import views
router = DefaultRouter(trailing_slash=False)
router = DefaultRouter()
router.register(r'stocksusa', views.StocksUsaViewSet)
urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
from django.conf.urls import include, url
from rest_framework.authtoken.views import obtain_auth_token
from FinDataUsa.urls import router
from FinDataUsa.views import StocksUsaViewSet as stockview
urlpatterns = patterns('',
url(r'^api/token/', obtain_auth_token, name='api-token'),
url(r'^api/v1/', include(router.urls)),
url(r'^api/v2/', include(router.urls)),
url(r'^admin/', include(admin.site.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^docs/', include('rest_framework_swagger.urls')),
)
The problem lies into the fact that the DefaultRouter uses the id lookup_field of your model for getting the object you want: For example this works:
GET localhost/api/v1/stocksusa/1
In order to provide extra parameters you need to hand-craft the urls like this:
url(r'(?P<year>\d{4})-(?P<month>\d{1,2})-(?P<day>\d{1,2})/(?P<code>\w+)$',
StocksUsaViewSet.as_view(),
name='stocks_detail'
),
The year month day code parameters are passed into your view with the kwargs dictionary:
self.kwargs['year']
self.kwargs['month']
self.kwargs['day']
self.kwargs['code']
On your get_object method you need to do something like that:
def get_object(self, queryset=None):
try:
date= datetime.date(
year=int(self.kwargs['year']),
month=int(self.kwargs['month']),
day=int(self.kwargs['day']),
)
except ValueError:
raise Http404
stock= get_object_or_404(Stocksusa, Ticker=self.kwargs['code'], Trade_Date=date)
return stock
Then you will have access to your object:

Categories