How to pass a dictionary in DestroyAPI SUccess MEssage - python

class ExampleDestroyView(DestroyAPIView):
serializer_class = PetSerializer
queryset = Pet.objects.all()
lookup_field = "object_id"
def perform_destroy(self, instance):
self.data = {}
self.data['status'] = True
approval()
self.data['msg'] = "It removed"
return self.data
Here is my Sample Class ..... In this I need to Delete an objet.... It's deleting
But I am unable to pass the following Dict As an OutPut
How can I pass the status and a message in a dictionary

Override the destroy(...) method
from rest_framework.generics import DestroyAPIView
from rest_framework.response import Response
from rest_framework import status
class ExampleDestroyView(DestroyAPIView):
serializer_class = PetSerializer
def destroy(self, request, *args, **kwargs):
instance = self.get_object()
data = self.perform_destroy(instance)
return Response(data=data, status=status.HTTP_204_NO_CONTENT)

from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
#api_view(['GET', 'POST'])
def snippet_list(request):
"""
List all code snippets, or create a new snippet.
"""
if request.method == 'GET':
snippets = Snippet.objects.all()
serializer = SnippetSerializer(snippets, many=True)
return Response(serializer.data)
elif request.method == 'POST':
serializer = SnippetSerializer(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)

Related

Django POST method for bulk creation using postman

I have POST method in views.py in django to create an entry in database
I can create a single entry using postman, but can not create bulk entries using postman
can anyone help, please?
models.py file
from django.db import models
class Users(models.Model):
user = models.CharField(max_length=50,default='')
function = models.CharField(max_length=50,default='')
department = models.CharField(max_length=50,default='')
logon = models.CharField(max_length=50,default='')
def __str__(self):
return self.user+" - Last_Logon: "+self.logon
class Meta:
ordering = ('id',)
serializers.py file
from rest_framework import serializers
from activities.models import Users
class UsersSerializer(serializers.ModelSerializer):
class Meta:
model = Users
fields = ('id', 'user', 'function', 'department', 'logon')
views.py file with GET,POST,PUT,DELETE, from this file POST method creates only a single entry
from django.shortcuts import render
from django.http.response import JsonResponse
from rest_framework.parsers import JSONParser
from rest_framework import status
from activities.models import Users
from activities.serializers import UsersSerializer
from rest_framework.decorators import api_view
#api_view(['GET', 'POST'])
def users_list(request):
if request.method == 'GET':
users = Users.objects.all()
user = request.GET.get('user', None)
if user is not None:
users = users.filter(user__icontains=user)
users_serializer = UsersSerializer(users, many=True)
return JsonResponse(users_serializer.data, safe=False)
# 'safe=False' for objects serialization
elif request.method == 'POST':
users_data = JSONParser().parse(request)
users_serializer = UsersSerializer(data=users_data)
if users_serializer.is_valid():
users_serializer.save()
return JsonResponse(users_serializer.data, status=status.HTTP_201_CREATED)
return JsonResponse(users_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
#api_view(['GET', 'PUT', 'DELETE'])
def users_detail(request, pk):
try:
users = Users.objects.get(pk=pk)
except Users.DoesNotExist:
return JsonResponse({'message': 'The user does not exist'}, status=status.HTTP_404_NOT_FOUND)
if request.method == 'GET':
users_serializer = UsersSerializer(users)
return JsonResponse(users_serializer.data)
elif request.method == 'PUT':
users_data = JSONParser().parse(request)
users_serializer = UsersSerializer(users, data=users_data)
if users_serializer.is_valid():
users_serializer.save()
return JsonResponse(users_serializer.data)
return JsonResponse(users_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
elif request.method == 'DELETE':
users.delete()
return JsonResponse({'message': 'User was deleted successfully!'}, status=status.HTTP_204_NO_CONTENT)
urls.py file
from django.urls import re_path
from activities import views
urlpatterns = [
re_path(r'^api/activities$', views.users_list),
re_path(r'^api/activities/(?P<pk>[0-9]+)$', views.users_detail),
]
if I set many=True in user serializer, UsersSerializer(data=users_data, many=True) for POST metho
In postman, for sending a single entry, got this error
for sending multiple entries, got this error
for UsersSerializer(data=users_data, many=True) you must send list of json objects
[
{
"User": "user1",
"function": "t",
"deportment": "t",
"logon": "23...."
},
{
"User": "user1",
"function": "t",
"deportment": "t",
"logon": "23...."
}
]
and for a user UsersSerializer(data=users_data)
you can split serializers with a send a query param into your url and in view function
if request.GET.get('bulk'):
serializer = UsersSerializer(data=users_data, many=True)
else:
serializer = UsersSerializer(data=users_data)

Django - Ignore certain fields on update depending on condition

Description:
The goal is to update all Spotlight fields on PUT/PATCH (update/partial update) if its status is YELLOW.
If status is RED || GREEN, it should update only its status and ignore any other fields. The workaround presented here is kind of smelly and it produces misleading responses when using PUT.
Is there any Django way to achieve this better than the presented workaround?
Workaround:
if instance.state == instance.STATE_YELLOW:
custom_data = request.data
else:
custom_data = {'state': request.data['state']}
Full code:
from stoplight.filters import StoplightFilter
from stoplight.models import Stoplight
from stoplight.permissions import (
IsSuperuserOrReadOnly
)
from stoplight.serializers import StoplightSerializer
from rest_framework import status
from rest_framework.mixins import CreateModelMixin, ListModelMixin, RetrieveModelMixin
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet
class StoplightViewSet(GenericViewSet, CreateModelMixin, ListModelMixin, RetrieveModelMixin):
"""
API endpoint for Stoplights
"""
queryset = Stoplight.objects.all()
serializer_class = StoplightSerializer
filter_class = StoplightFilter
search_fields = ('name',)
permission_classes = (IsSuperuserOrReadOnly,)
def update(self, request, *args, **kwargs):
"""
Updates Stoplight state
"""
partial = kwargs.pop('partial', False)
instance = self.get_object()
if instance.state == instance.STATE_YELLOW:
custom_data = request.data
else:
custom_data = {'state': request.data['state']}
serializer = self.get_serializer(instance, data=custom_data, partial=partial)
serializer.is_valid(raise_exception=True)
self.perform_update(serializer)
if getattr(instance, '_prefetched_objects_cache', None):
# If 'prefetch_related' has been applied to a queryset, we need to
# forcibly invalidate the prefetch cache on the instance.
instance._prefetched_objects_cache = {}
return Response(serializer.data, status=status.HTTP_200_OK)
def perform_update(self, serializer):
serializer.save()
def partial_update(self, request, *args, **kwargs):
kwargs['partial'] = True
return self.update(request, *args, **kwargs)

Can't get a GET response in DJango Rest

I'm trying to learn DJango Rest so I made a litte test to see if I could obtain some things from the database, but I'm getting some problems.
Here's my models.py:
from django.db import models
# Create your models here.
class Stock(models.Model):
ticker = models.CharField(max_length=10)
open = models.FloatField()
close = models.FloatField()
volume = models.IntegerField()
def __str__(self):
return self.ticker
Here's my serializers.py:
from rest_framework import serializers
from .models import Stock
class StockSerializer(serializers.ModelSerializer):
ticker = serializers.CharField()
open = serializers.FloatField()
close = serializers.FloatField()
volume = serializers.IntegerField()
def create(self, validated_data):
return Stock.objects.check(**validated_data)
def update(self, instance, validated_data):
instance.ticker = validated_data.get('ticker', instance.ticket)
instance.open = validated_data.get('open', instance.open)
instance.close = validated_data.get('close', instance.close)
instance.volume = validated_data.get('volume', instance.volume)
instance.save()
return instance
class Meta:
model = Stock
fields = '__all__'
Here's my views.py:
from django.http import Http404
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.views import APIView
from .models import Stock
from .serializers import StockSerializer
# List all stocks or create a new one
# stocks/
#api_view(['GET', 'POST'])
def stock_list(request, format=None):
if request.method == 'GET':
stocks = Stock.objects.all()
serializer = StockSerializer(stocks, many=True)
return Response(serializer.data)
elif request.method == 'POST':
serializer = StockSerializer(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)
#api_view(['GET', 'POST', 'DELETE'])
def stock_detail(request, pk, format=None):
try:
stock = Stock.objects.get(pk=pk)
except Stock.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
if request.method == 'GET':
serializer = StockSerializer(stock)
return Response(serializer.data)
elif request.method == 'PUT':
serializer = StockSerializer(stock, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
elif request.method == 'DELETE':
stock.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
And finally, here's my url.py:
from django.conf.urls import url
from django.contrib import admin
from rest_framework.urlpatterns import format_suffix_patterns
from companies import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^stocks/', views.stock_list),
url(r'^stocks/(?P<pk>[0-9]+)$', views.stock_detail),
]
urlpatterns = format_suffix_patterns(urlpatterns)
I've been following this tutorial, but when it comes to the moment of making some requests (for this example I use this one: http http://127.0.0.1:8000/stocks/
I get this error message:
TypeError at /stocks/ stock_list() missing 1 required positional
argument: 'request'
I think that the problem is with the urls, but I'm not sure how to fix it.
Any ideas and some examples?
UPDATE: The problem was with the methods in view (they had an attibute self)
The general Get method works, but when I try to use POST
POST ERROR:
When I try this request: http --form POST http://127.0.0.1:8000/stocks/ ticker='SAM'
I get this error:
AttributeError at /stocks/ Got AttributeError when attempting to get a
value for field ticker on serializer StockSerializer. The
serializer field might be named incorrectly and not match any
attribute or key on the list instance. Original exception text was:
'list' object has no attribute 'ticker'.
You need to remove self.
Remember you are using functions not clases.
#api_view(['GET', 'POST'])
def stock_list(request, format=None):
if request.method == 'GET':
stocks = Stock.objects.all()
serializer = StockSerializer(stocks, many=True)
return Response(serializer.data)
elif request.method == 'POST':
serializer = StockSerializer(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)
Try views.stock_list.as_view() in urls.py

Django simple authentication application

I need for a project a simple backend with the following functionality (all must be done via an API since this will be accessed by another program):
User can not do anything if he is not authenticated
In order to get authenticated the user knows "DEFAULT USER" credentials
2.1 The user tries to log in with the "DEFAULT USER" credentials
2.2 The application creates a new User with random pass and username (or token) and returns it to the user so that he can later use those new credentials to authenticate with the server
Authenticated users will only be able to CREATE 1 entry in the DB or update the entry created by them.
I have been trying to do this for the past few days however, all the django tutorials I managed to find for DJANGO-REST-FRAMEWORK did not help me.
Currently this is what I got:
urls.py
from django.conf.urls import url
from rest_framework.urlpatterns import format_suffix_patterns
from api import views
from api.serializers import UserSerializer
urlpatterns = [
url(r'^api-classes/$', views.UserStatisticsList.as_view()),
url(r'^api/$', views.userStatistics_list),
url(r'^users/$', views.UserList.as_view()),
]
urlpatterns = format_suffix_patterns(urlpatterns)
serializers.py:
from rest_framework import serializers
from api.models import UserStatistics
from django.contrib.auth.models import User
class UserStatisticsSerializer(serializers.ModelSerializer):
user = serializers.ReadOnlyField(source='user.username')
class Meta:
model = UserStatistics
fields = ('id','user', 'last_modified', 'statistics_json',)
def create(self, validated_data):
"""
Create and return a new `UserStatistics` instance, given the validated data.
"""
return UserStatistics.objects.create(**validated_data)
def update(self, instance, validated_data):
"""
Update and return an existing `UserStatistics` instance, given the validated data.
"""
instance.last_modified = validated_data.get('last_modified', instance.last_modified)
instance.statistics_json = validated_data.get('statistics_json', instance.statistics_json)
instance.save()
return instance
class UserSerializer(serializers.ModelSerializer):
# userStat = serializers.PrimaryKeyRelatedField(many=False, queryset=UserStatistics.objects.all())
class Meta:
model = User
fields = ('id', 'username',)
# fields = ('id', 'username', 'userStat')
views.py:
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response
from api.models import UserStatistics
from api.serializers import UserStatisticsSerializer, UserSerializer
from rest_framework import permissions
#api_view(['GET', 'POST'])
def userStatistics_list(request, format=None):
"""
List all code snippets, or create a new snippet.
"""
if request.method == 'GET':
userStat = UserStatistics.objects.all()
serializer = UserStatisticsSerializer(userStat, many=True)
return Response(serializer.data)
elif request.method == 'POST':
serializer = UserStatisticsSerializer(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)
from rest_framework import mixins
from rest_framework import generics
class UserStatisticsList(
mixins.ListModelMixin,
mixins.CreateModelMixin,
generics.GenericAPIView):
"""
List all UserStatistics, or create a new UserStatistics.
"""
queryset = UserStatistics.objects.all()
serializer_class = UserStatisticsSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
def perform_create(self, serializer):
serializer.save(user=self.request.user)
# def get(self, request, format=None):
# userStat = UserStatistics.objects.all()
# serializer = UserStatisticsSerializer(userStat, many=True)
# return Response(serializer.data)
# def post(self, request, format=None):
# serializer = UserStatisticsSerializer(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)
from django.contrib.auth.models import User
class UserList(generics.ListAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
models.py:
from django.db import models
from jsonfield import JSONField
from django.contrib.auth.models import User
# Create your models here.
class UserStatistics(models.Model):
last_modified = models.DateTimeField(auto_now_add=True)
statistics_json = JSONField()
user = models.OneToOneField(User, related_name="creator")
class Meta:
ordering = ('last_modified','statistics_json',)
I also tried to implement a custom Authenticator which in my understanding is what gets called when an User wants to Authenticate ... :
import string
import random
from django.contrib.auth.models import User, check_password, ModelBackend
class SettingsBackend(ModelBackend):
"""
Authenticate against the settings ADMIN_LOGIN and ADMIN_PASSWORD.
Use the login name, and a hash of the password. For example:
ADMIN_LOGIN = 'admin'
ADMIN_PASSWORD = 'sha1$4e987$afbcf42e21bd417fb71db8c66b321e9fc33051de'
"""
ANDROID_LOGIN_USERNAME = "android"
ANDROID_LOGIN_PASSWORD = "android"
def authenticate(self, username=None, password=None):
login_valid = (ANDROID_LOGIN_USERNAME == username)
pwd_valid = check_password(password, ANDROID_LOGIN_PASSWORD)
if login_valid and pwd_valid:
# try:
# user = User.objects.get(username=username)
# except User.DoesNotExist:
# return None
# Create a new user. Note that we can set password
# to anything, because it won't be checked; the password
# from settings.py will.
user = User(username=random_string_generator(), password=random_string_generator())
user.save()
return user
return None
def random_string_generator(size=6, chars=string.ascii_uppercase + string.digits):
return ''.join(random.choice(chars) for _ in range(size))
def has_perm(self, user_obj, perm, obj=None):
if user_obj.username == settings.ANDROID_LOGIN_USERNAME:
return True
else:
return False
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
Can someone please point out what to do next ?
Thank you

Django Rest Framework: issue with request.data

I am attempting to use Django rest framework for my server implementation. I get the following error when I attempt to POST.
'WSGIRequest' object has no attribute 'data'
Here is the code for the view.py
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response
from whiteboards.models import Whiteboard, Path, Point
from whiteboards.serializers import WhiteboardSerializer
#api_view(['GET', 'POST'])
def whiteboard_list(request):
"""
List all whiteboards, or create a new whiteboard.
"""
if request.method == 'GET':
print('GET')
whiteboards = Whiteboard.objects.all()
serializer = WhiteboardSerializer(whiteboards, many=True)
return Response(serializer.data)
elif request.method == 'POST':
print('POST')
d = request.data
print('data broke')
serializer = WhiteboardSerializer(data=d)
print("created serializer")
if serializer.is_valid():
serializer.save()
print("It's valid")
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
In version 3 (latest) - request.DATA has been replaced with request.data:
user = dict(
full_name=request.data['full_name'],
password=request.data['password'],
email=request.data['email']
)
In version 2 - it was request.DATA:
user = dict(
full_name=request.DATA['full_name'],
password=request.DATA['password'],
email=request.DATA['email']
)
try request.DATA instead of request.data

Categories