Handling JSON Post request in Django rest framework - python

I want to create model entity in database using POST request. GET is working fine but POST is not being triggered. views.py is as follows:
<code>
from django.shortcuts import render
from rest_framework import viewsets, generics
from server_app.serializers import DataSerializer
from server_app.models import DataModel
from rest_framework.views import APIView
from rest_framework.parsers import JSONParser
from rest_framework.renderers import JSONRenderer
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from server_app.serializers import DataSerializer
import logging
import json
from django.http import HttpResponse
from django.views.generic import View
class MyView(View):
def get(self, request, *args, **kwargs):
return HttpResponse('This is GET request')
def post(self, request, *args, **kwargs):
return HttpResponse('This is POST request')
class JSONResponse(HttpResponse):
def __init__(self, data, **kwargs):
content = JSONRenderer().render(data)
kwargs['content_type'] = 'application/json'
super(JSONResponse, self).__init__(content, **kwargs)
logger = logging.getLogger(__name__)
#csrf_exempt
def DataModel_list(request):
if request.method == 'GET':
logger.error("GET DATA SERVER")
queryset = DataModel.objects.all()
serializer_class = DataSerializer(queryset, many=True)
#return HttpResponse(json.dumps(serializer_class.data),content_type="application/json")
return JSONResponse(serializer_class.data)
elif request.method == 'POST':
logger.error("POST DATA SERVER")
json_data = JSONParser().parse(request)
serializer_class = DataSerializer(data=json_data)
if serializer_class.is_valid():
serializer_class.save()
return JSONResponse(serializer_class.data, status=201)
return JSONResponse(serializer_class.errors, status=400)
</code>
And following is my urls.py
<code>
from django.conf.urls import patterns, include, url
from rest_framework import routers
from django.contrib import admin
from server_app import views
admin.autodiscover()
urlpatterns = patterns('',
url(r'^getDataModel/$', views.DataModel_list),
url(r'^admin/', include(admin.site.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
)
</code>
And serializers.py
<code>
from rest_framework import serializers
from server_app.models import DataModel
class DataSerializer(serializers.ModelSerializer):
class Meta:
model = DataModel
fields = ('first_name', 'last_name', 'chapter', 'category', 'email', 'mantinada')
</code>
models.py
<code>
from django.db import models
# Create your models here.
class DataModel(models.Model):
first_name = models.CharField(max_length = 200)
last_name = models.CharField(max_length = 200)
chapter = models.CharField(max_length = 200)
category = models.CharField(max_length = 200)
email = models.CharField(max_length = 200)
mantinada = models.CharField(max_length = 200)
</code>
I have put logger in GET and POST requests. When I access url for GET I can see the results and logger consoles but for POSt request, i am not getting any logger information. Can anyone please tell me what I am missing?
Thanks in advance.

There was nothing wrong at the django server end. I was calling wrongly from the android-client side because the keys in the android json object were different from fields in models. Correcting the keys have solved the problem.

Related

Couldnot resolve URL for hyperlinked relationship using view name "snippet-detail"or incorrectly configured the `lookup_field` attribute on this field

ImproperlyConfigured at /snippet/5
Could not resolve URL for hyperlinked relationship using view name "snippet-detail". You may have failed to include the related model in your API, or incorrectly configured the lookup_field attribute on this field.
models.py
from email.policy import default
import imp
from tkinter import CASCADE
from django.db import models
from pygments.lexers import get_all_lexers
from pygments.styles import get_all_styles
from pygments.lexers import get_lexer_by_name
from pygments.formatters.html import HtmlFormatter
from pygments import highlight
from django.contrib.auth.models import User
import snippets
# Create your models here.
LEXERS=[item for item in get_all_lexers() if item[1]]
LANGUAGE_CHOICES=sorted([(item[1][0],item[0]) for item in LEXERS])
STYLE_CHOICES=sorted([(item,item)for item in get_all_styles()])
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=250,default="0")
linenos=models.BooleanField(default=False)
language=models.CharField(choices=LANGUAGE_CHOICES,default='python',max_length=100)
style=models.CharField(choices=STYLE_CHOICES,default='friendly',max_length=100)
owner=models.ForeignKey('auth.User',related_name='snippets',on_delete=models.CASCADE)
class Meta:
ordering=['created']
permissions.py
import imp
from rest_framework import permissions
class IsOwnerReadOnly(permissions.BasePermission):
"""custom permissions to only allow owners of an oject to edit
"""
def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS:
return True
return obj.owner == request.user
serializers.py
from operator import mod
from numpy import source
from .models import *
from rest_framework import serializers
from snippets.models import Snippet, LANGUAGE_CHOICES,STYLE_CHOICES
class SnippetSerializer(serializers.HyperlinkedModelSerializer):
owner = serializers.ReadOnlyField(source='owner.username')
class Meta:
model=Snippet
fields = ['url', 'id', 'owner',
'created', 'title', 'linenos', 'language', 'style']
# fields='__all__'
# fields=['id','url','owner']
from django.contrib.auth.models import User
class UserSerializer(serializers.HyperlinkedModelSerializer):
snippets=serializers.HyperlinkedRelatedField(lookup_field = 'username',many=True,view_name='snippet-details',read_only=True)
owner=serializers.ReadOnlyField(source='owner.username')
class Meta:
model= User
fields=['id','username','snippets','owner']
views.py
from snippets.models import Snippet
from snippets.permissions import IsOwnerReadOnly
from snippets.serializers import SnippetSerializer
from rest_framework import generics
from snippets.permissions import IsOwnerReadOnly
from rest_framework import permissions
class snippet_list(generics.ListCreateAPIView):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
class snippet_detail(generics.RetrieveUpdateDestroyAPIView):
permission_classes=[permissions.IsAuthenticatedOrReadOnly,IsOwnerReadOnly]
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
########################## authentication purspose #####################################################
from django.contrib.auth.models import User
from .serializers import *
from rest_framework import permissions
class UserList(generics.ListAPIView):
permission_classes=[permissions.IsAuthenticatedOrReadOnly]
queryset = User.objects.all()
serializer_class = UserSerializer
class UserDetail(generics.RetrieveAPIView):
permission_classes=[permissions.IsAuthenticatedOrReadOnly]
queryset = User.objects.all()
serializer_class = UserSerializer
####################################### using hyperlinking for relationships #################################################################
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.reverse import reverse
#api_view(['GET'])
def api_root(request, format=None):
return Response({
'users': reverse('user-list', request=request, format=format),
'snippets': reverse('snippet-list', request=request, format=format)
})
urls.py(api)
from rest_framework.urlpatterns import format_suffix_patterns
from django.urls import path,include
from snippets import views
from .views import *
urlpatterns=format_suffix_patterns([path('',views.api_root),
path('snippet/',views.snippet_list.as_view(),name='snippet-list'),
path('snippet/<int:pk>',views.snippet_detail.as_view(),name='snippet-details'),
path(' ',views.UserList.as_view(),name='user-list'),
path('Users/<int:pk>',views.UserDetail.as_view(),name='user-details'),
])
urls.py(main project)
from django.contrib import admin
# from snippets.urls import *
# from snippets.views import *
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('snippets.urls')),
]
########################## authentication purspose #####################################################
urlpatterns += [
path('api-auth/', include('rest_framework.urls')),
]
I'm new for django but learning and implementing and also sorting errors. But I got stuck with this error for 2 days. I done many changes but still not working .
It appears to me that you misspelled the url name in the urls.py
You have
path('snippet/<int:pk>',views.snippet_detail.as_view(),name='snippet-details'),
replace it with
path('snippet/<int:pk>',views.snippet_detail.as_view(),name='snippet-detail')
remove the "s" from the name

Retrieving images from Django from rest_framework

models.py:
from __future__ import unicode_literals
from django.db import models
class Photo(models.Model):
title = models.CharField(max_length=255, blank=True)
file = models.FileField()
uploaded_at = models.DateTimeField(auto_now_add=True)
serializers.py:
from rest_framework import serializers
from . models import Photo
class imageSerializer(serializers.ModelSerializer):
class Meta:
model = Photo
fields='__all__'
views.py:
from django.shortcuts import render,redirect
from django.http import JsonResponse
from django.views import View
import time
from rest_framework import generics
from .forms import PhotoForm
from .models import Photo
from django.http import HttpResponse
from rest_framework.response import Response
from django.shortcuts import get_object_or_404
from rest_framework.views import APIView
from rest_framework import status
from .serializers import imageSerializer
import requests
class DragAndDropUploadView(View):
def get(self, request):
photos_list = Photo.objects.all()
return render(self.request, 'UploadMulti/drag_and_drop_upload/index.html', {'photos': photos_list})
def post(self, request):
form = PhotoForm(self.request.POST, self.request.FILES)
if form.is_valid():
photo = form.save()
data = {'is_valid': True, 'name': photo.file.name, 'url': photo.file.url}
else:
data = {'is_valid': False}
return JsonResponse(data)
def clear_database(request):
for photo in Photo.objects.all():
photo.file.delete()
photo.delete()
return redirect(request.POST.get('next'))
class ImagesList(APIView):
def get(self,request):
imagelist=Photo.objects.all()
serializer = imageSerializer(imagelist,many=True)
return Response(serializer.data)
def post(self):
pass
def backend(request):
response = requests.get('http://localhost:8000/images/')
api_values = response.json()
for values in api_values:
print(type(values['file']))
return render(request,"home.html",{'data':api_values})
when I print type of values.file which is the image data I am getting as therefore when sending it to frontend the image is not displayed
How to retrieve as image file from rest api?
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
[
{
"id": 1,
"title": "",
"file": "think-twice-code-once.jpg",
"uploaded_at": "2019-11-27T12:34:32.270786Z"
}
]
Is there any other method to obtain images from rest framework and whether the image is stored as Image format ?
The issue is due to your configuration of FileField for this particular serializer. You need use_url to be True. So you can either change the UPLOADED_FILES_USE_URL setting or set use_url=True in imageSerializer as seen below.
class imageSerializer(serializers.ModelSerializer):
class Meta:
model = Photo
fields='__all__'
file = serializers.FileField(use_url=True)
Side note, imageSerializer should really be ImageSerializer to follow the python class naming guidelines.

ImproperlyConfigured DeletePost's select_related property

So I'm trying to enable the currently logged in user to delete their own post on my site. I'm using a DeleteView with select_related mixing. I keep getting an error that says it's improperly configured and needs to be a tuple or a list. Here is the error, my post models, and views. Not really sure where to go from here, and this doesn't seem to be a very popular error as I'm not really able to find much with a Google search.
Error:
ImproperlyConfigured at /colorsets/delete/7/
DeletePost's select_related property must be a tuple or list.
App Views.py
from django.shortcuts import render
from colorsets.forms import ColorForm
from colorsets import models
from colorsets.models import ColorSet
from django.utils import timezone
from django.contrib.auth import authenticate,login,logout
from django.http import HttpResponseRedirect, HttpResponse
from django.core.urlresolvers import reverse,reverse_lazy
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from braces.views import SelectRelatedMixin
from django.views.generic import (TemplateView,ListView,
DetailView,CreateView,
UpdateView,DeleteView)
# Create your views here.
#def index(request):
# return render(request,'index.html')
class PostListView(ListView):
model = ColorSet
def get_queryset(self):
return ColorSet.objects.filter(published_date__lte=timezone.now()).order_by('-published_date')
class CreateColorSetView(LoginRequiredMixin,CreateView):
login_url = '/login/'
redirect_field_name = 'index.html'
form_class = ColorForm
model = ColorSet
def form_valid(self,form):
self.object = form.save(commit=False)
self.object.user = self.request.user
self.object.save()
return super().form_valid(form)
class DeletePost(LoginRequiredMixin,SelectRelatedMixin,DeleteView):
model = models.ColorSet
select_related = ('user')
success_url = reverse_lazy('index')
def get_queryset(self):
queryset = super().get_queryset()
return queryset.filter(user_id=self.request.user.id)
def delete(self,*args,**kwargs):
messages.success(self.request,'Post Deleted')
return super().delete(*args,**kwargs)
App models.py
from django.db import models
from django.core.urlresolvers import reverse
from django.conf import settings
from django.contrib.auth import get_user_model
User = get_user_model()
# Create your models here.
class ColorSet(models.Model):
user = models.ForeignKey(User,related_name='colorset')
published_date = models.DateTimeField(auto_now_add=True)
name = models.CharField(max_length=50,blank=False)
color_one = models.CharField(max_length=6,blank=False,default='cccccc')
color_two = models.CharField(max_length=6,blank=False,default='ffffff')
color_three = models.CharField(max_length=6,blank=False,default='e5e5e5')
color_four = models.CharField(max_length=6,blank=False,default='f0f0f0')
color_five = models.CharField(max_length=6,blank=False,default='bababa')
def publish(self):
self.save()
def get_absolute_url(self):
return reverse('index')
def __str__(self):
return self.name
Traceback:
Let me know if you need to see anything else.
You are missing the comma to make select_related a tuple.
select_related = ('user',)
Without the comma, ('user') is the string 'user'.

django rest framework post method giving error "Method "POST" not allowed"

I am getting error 'Method "POST" not allowed' while running the api. I am new to DRF and don’t know what i am doing wrong.
the GET method is working fine. I have problem with POST method.
my code is given below
view.py:
from django.contrib.auth.models import User
from django.http import Http404
from django.shortcuts import get_object_or_404
from restapp.serializers import UserSerializer
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django.http import HttpResponse
class UserList(APIView):
def get(self, request, format=None):
users = User.objects.all()
serializer = UserSerializer(users, many=True)
return Response(serializer.data)
def post(self, request, format=None):
serializer = UserSerializer(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)
serializer.py:
from django.contrib.auth.models import User
from .models import Question,Choice
from rest_framework import serializers
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', 'username', 'first_name', 'last_name', 'email')
url.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
from restapp import views
admin.autodiscover()
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^users/', views.UserList.as_view()),)
You have improper indentation in your code. The post method needs to be inside the UserList(APIView) class. Right now is defined as a standalone function.

DRF AttributeError type object 'QuerySet' has no attribute 'nom'

I'm making my first DRF api I get a strange AttributeError that I don't understand. When I try to access to my data using a GET request, I get this error:
Got AttributeError when attempting to get a value for field nom on
serializer ExpediteurSerializer. The serializer field might be named
incorrectly and not match any attribute or key on the type instance.
Original exception text was: type object 'QuerySet' has no attribute
'nom'.
I guess I've done something unexpected in my serializers.py file.. Here follows some snippets of my code.
models.py
from django.db import models
# Create your models here.
class Expediteur(models.Model):
nom = models.CharField(max_length=50)
prenom = models.CharField(max_length=100)
adresse = models.CharField(max_length=200)
tel = models.IntegerField()
views.py
from django.shortcuts import render
from rest_framework import viewsets
from rest_framework.views import APIView
from rest_framework.response import Response
from polls.serializers import ExpediteurSerializer, DestinataireSerializer, LettrePrioSerializer, TypeLettreRecoSerializer, LettreRecoSerializer, TimbrePrioSerializer, TimbreRecoSerializer
from polls.models import Expediteur, Destinataire, LettrePrio, TypeLettreReco, LettreReco, TimbrePrio, TimbreReco
from rest_framework import status, HTTP_HEADER_ENCODING
from django.shortcuts import render, get_object_or_404
import json
import datetime
from django.http import HttpResponseRedirect, HttpResponse, Http404
from django.shortcuts import render, get_object_or_404
from django.core.urlresolvers import reverse
from django.contrib.auth.decorators import user_passes_test
from django.contrib.auth import login
from django.core.exceptions import ObjectDoesNotExist
from django.views.decorators.csrf import csrf_exempt
from django.utils.timezone import get_current_timezone
# Create your views here.
class ExpeViewSet(APIView):
serializer_class = ExpediteurSerializer
def get(self, request):
queryset = Expediteur.objects.all()
serializer = ExpediteurSerializer(queryset)
return Response(serializer.data)
def post(self, request):
serializer = self.serializer_class(data=request.DATA)
return Response(status=status.HTTP_201_CREATED)
serializers.py
from rest_framework import serializers
from polls.models import Expediteur, Destinataire, LettrePrio, TypeLettreReco, LettreReco, TimbrePrio, TimbreReco
class ExpediteurSerializer(serializers.Serializer):
nom = serializers.CharField(required=True, allow_blank=False, max_length=50)
prenom = serializers.CharField(required=True, allow_blank=False, max_length=100)
adresse = serializers.CharField(required=True, allow_blank=False, max_length=200)
tel = serializers.IntegerField(required=True)
def create(self, validated_data):
return Expediteur.objects.create(**validated_data)
def update(self, instance, validated_data):
instance.nom = validated_data.get('nom', instance.nom)
instance.prenom = validated_data.get('prenom', instance.prenom)
instance.adresse = validated_data.get('adresse', insatnce.adresse)
instance.tel = validated_data.get('tel', instance.tel)
instance.save()
return instance
I think you are missing the many flag in you view, like so:
ExpediteurSerializer(queryset, many=True)
In general you could simplify your code very much by fully utilizing DRF.
First, make ExpediteurSerializer a ModelSerializer according to the documentation.
Then you can also get rid of the create and update method, DRF takes care of all of that for you. And I strongly recommend you to look at ModelViewSets, they make your life very easy.

Categories

Resources