How to get rid of not existing errors? - python

Here is my code
from rest_framework.decorators import api_view
from rest_framework.permissions import IsAuthenticated, AllowAny
from rest_framework.response import Response
from rest_framework import viewsets, status
from .models import Actor
from .serializers import ActorSerializer
# Create your views here.
class ActorView(viewsets.ModelViewSet):
model = Actor
queryset = model.objects.all()
permission_classes = (AllowAny,)
serializer_class = ActorSerializer
http_method_names = ['get', 'post', 'put', 'delete']
def list(self, request):
serializer = ActorSerializer(self.queryset, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
def create(self, request):
serializer = ActorSerializer(data=request.data)
if serializer.is_valid(raise_exception=True):
print(serializer.validated_data['name'])
return Response("OK", status=status.HTTP_200_OK)
else:
return Response("nie ok")
Pylance thinks that this line:
print(serializer.validated_data['name'])
is incorrect, but it is correct. Code works fine and it doesn't displaying any errors while server is running and request is sent. But it is underlined in red, so something must be wrong. How can i get rid of those "errors"?
"__getitem__" method not defined on type "empty"
Object of type "None" is not subscriptable
I have alredy tried uninstalling Pylance and changing its' version but all for nothing.

Related

"JSON parse error - Expecting property name enclosed in double quotes: line 1 column 2 (char 1)"

I am creating a project with Django Rest Framework and I ran into some problems and im not able to fix them.
So, I have a URL for post method and when I post there using postman, I get an error:
{
"detail": "JSON parse error - Expecting property name enclosed in double quotes: line 1 column 2 (char 1)"
}
This is the data im sending:
{username:"REQUAB", password:"REQUAB", emailId:"requab#gmail.com"}
And just to check if i had some problem in the serializer or the model, i did a normal get request and i got correct output.
my models.py:
from django.db import models
# Create your models here.
class User(models.Model):
emailId = models.EmailField(max_length=50)
username = models.CharField(max_length=20)
password = models.CharField(max_length=50)
recipes = models.IntegerField(default=0)
def __str__(self):
return self.username
my serializers.py:
from rest_framework import serializers
from .models import User
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['id', 'username', 'emailId', 'password', 'recipes']
my urls.py:
from django.urls import path
from .views import UsersList, UsersDetail
urlpatterns = [
path('', UsersList.as_view()),
]
my views.py:
from django.http import Http404
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from users.models import User
from .serializers import UserSerializer
# Create your views here.
class UsersList(APIView):
def get(self, request, format=None):
users = User.objects.all()
serializer = UserSerializer(users, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
def post(self, request):
print(request.data)
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)
Pls help me with this (Thanks, in advance).
The error is pretty clear, try to enclose the property names in double quotes or use JSON.stringify when sending it (using JS).

How to make multiple object in one request put or delete? Django Rest

It allow me to pass in json format data to post for creating record after i make def create so that json format like [{data:data,data:data}] can post in. How should i do so that i can also make put request with multiple object in one request or using post method to update?
Below is views.py.
from django.shortcuts import render
from .models import ListForm
# Create your views here.
from rest_framework import viewsets
from .serializers import ListFormSerializer
from rest_framework import filters
import django_filters.rest_framework
from rest_framework.response import Response
from rest_framework import status, viewsets
class ListFormViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows users to be viewed or edited.
"""
queryset = ListForm.objects.all().order_by('group')
serializer_class = ListFormSerializer
filter_backends = (django_filters.rest_framework.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter,)
filterset_fields = ['group','key_description']
search_fields = ['group']
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data, many=isinstance(request.data,list))
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
# return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
Maybe you need something like this:
from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework.decorators import action
import json
from .models import Post
from .serializers import PostSerializer
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.none()
serializer_class = serializers.PostSerializer
#action(detail=False, methods=['post'])
def update_this(self, request):
try:
data = json.loads(request.data)
except:
try:
data = dict(request.data)
except:
data = request.data
# You can do everything you want here with data
return Response({'code': 0, 'desc': 'OK', 'more_data': {}})

"POST /user/create/ HTTP/1.1" 500 82190

I am having a problem setting up authentication in django rest. Everytime I try to create a user using a post request to this url http://127.0.0.1:8000/user/create/ I get this error: AssertionError: Expected a Response, HttpResponse or HttpStreamingResponse to be returned from the view, but received a <class 'NoneType'>
[09/Apr/2021 14:41:43] "POST /user/create/ HTTP/1.1" 500 82190. I have tried may solutions here with no success.
views.py
from rest_framework_simplejwt.views import TokenObtainPairView
from rest_framework.views import APIView
from rest_framework import status, permissions
from rest_framework.response import Response
from .serializers import TokenObtainPairSerializer
from rest_framework.generics import CreateAPIView
from .serializers import CustomUserSerializer, MyTokenObtainPairSerializer
class CustomUserCreate(APIView):
permission_classes = (permissions.AllowAny,)
def post(self, request, format = 'json'):
serializer = CustomUserSerializer(data= request.data)
if serializer.is_valid():
user = serializer.save()
if user:
json = serializer.data
return Response(status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
serializers.py
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework import serializers
from .models import CustomUser
class CustomUserSerializer(serializers.ModelSerializer):
email = serializers.EmailField(required=True)
username = serializers.CharField()
password = serializers.CharField(min_length = 8, write_only= True)
class Meta:
model = CustomUser
fields = ('email', 'username', 'password')
extra_kwargs = {'password': {'write_only': True}}
def create(self, validated_data):
password = validated_data.pop('password', None)
instance = self.Meta.model(**validated_data)
if password is not None:
instance.set_password(password)
instance.save()
return instance
urls.py
from django.urls import path
from rest_framework_simplejwt import views as jwt_views
from .views import ObtainTokenPairWithColorView, CustomUserCreate, HelloWorld
urlpatterns = [
path('user/create/', CustomUserCreate.as_view(), name="create_user"),
]
Your view does not return anything when serializer.is_valid() returns False. In that case you need to produce a response as well. Likely this is due to bad indentation:
class CustomUserCreate(APIView):
permission_classes = (permissions.AllowAny,)
def post(self, request, format = 'json'):
serializer = CustomUserSerializer(data= request.data)
if serializer.is_valid():
user = serializer.save()
if user:
json = serializer.data
return Response(status=status.HTTP_201_CREATED)
# outside the body of the if clause
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Adding response for post in ModelViewset

I have to provide a DB status response (which tells if the serializer gets stored or not) after a POST request in ModelViewSet. Please help me perform that in the view.
from django.shortcuts import render
from .models import Booking
from rest_framework import viewsets
from .serializers import BookingSerializer
class BookingViewSet(viewsets.ModelViewSet):
queryset = Booking.objects.all()
serializer_class = BookingSerializer
Just a 200 or 201 will do and django already handles this. If you want to override the response message
Here is a snippet
from rest_framework.response import Response
from rest_framework import status
def create(self, request, *args, **kwargs):
...
return Response({'success': 'Data successfully submitted'}, status=status.HTTP_200_OK)

API call to update a field of an object

So I have an model serializer which consists of
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', 'name', 'description')
This is my ViewSet
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
This is my URLs.py file:
from django.conf.urls import include, url
from rest_framework import routers
import views
router = DefaultRouter()
router.register('user', views.UserViewSet)
urlpatterns = [
url(r'^', include(router.urls)),
url(r'^login/', include('rest_framework.urls', namespace='rest_framework'))
]
Using the serializer, I can make it print out the objects inside my database. If I have the object PK/ID, I want to be able to update the field id or name of the object. Is there a way I can do that with a patch/post request using the serializer? I'm new to this so I'd love it if someone can help me out with this.
I'm thinking of just doing a POST request, then have it do this:
user = User.objects.get(id=id)
user.name = "XXXXX"
user.save()
But I want to do this using the serializer, using a PATCH request.
the below code will help to you,
**filename : views.py**
from user.models import User
from users.serializers import UserSerializer
from django.http import Http404
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
class UserList(APIView):
"""
List all users, or create a new user.
"""
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)
class UserDetail(APIView):
"""
Retrieve, update or delete a user instance.
"""
def get_object(self, pk):
try:
return User.objects.get(pk=pk)
except User.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
user = self.get_object(pk)
serializer = UserSerializer(user)
return Response(serializer.data)
def put(self, request, pk, format=None):
user = self.get_object(pk)
serializer = UserSerializer(user, 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):
user = self.get_object(pk)
user.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
**filename : urls.py**
from django.conf.urls import url
from rest_framework.urlpatterns import format_suffix_patterns
from users import views
urlpatterns = [
url(r'^users/$', views.UserList.as_view()),
url(r'^user/(?P<pk>[0-9]+)/$', views.UserDetail.as_view()),
]
urlpatterns = format_suffix_patterns(urlpatterns)
Reference : http://www.django-rest-framework.org/tutorial/3-class-based-views/
Django rest framework comes with some pre-defined concrete generic views such as UpdateAPIView, RetrieveUpdateAPIView.
First you need to create a view for user which uses one of the views which can update. The update views provides handlers for patch method on the view.
RetrieveUpdateAPIView
Used for read or update endpoints to represent a single model instance.
Provides get, put and patch method handlers.
Now, use this to create a view:
class UserDetail(generics.RetrieveUpdateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
To access this view you need to have a url which uses user's primary key to access the user:
url(r'users/(?P<pk>\d+)/$', UserDetail.as_view(), name='api-user-detail'),
Then using PATCH call you can update the user's name.
Since you're using a ModelViewset, this capability should be built in. If you use the browsable API to navigate to /user/<pk>/, you'll see the operations you can perform on that object. By default, a ModelViewset provides list(), retrieve(), create(), update(), and destroy() capability.
http://www.django-rest-framework.org/api-guide/viewsets/#modelviewset
You can also override any or all of the provided methods, however an update of a single object is built in to DRF ModelViewsets. Use curl to try a PATCH to /user/<pk>/ with the information you'd like to update.

Categories

Resources