Django Rest Framework (Rest API): 'function' object has no attribute 'as_view' - django-rest-framework

I am trying to generate class based view by using Django Rest framework. customer_details is a django app name. There is an error when I am trying to call that view in urls.py is:
\customer_details\urls.py", line 15, in path('ca_number/',views.CustomerDetailView.as_view()), AttributeError: 'function' object has no attribute 'as_view'
Here is some code:
customer_details/views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import CustomerDetailModel
from .serializer import CustomerDetailSerializer
class CustomerDetailView(APIView):
def get(self, request, ca_number):#get all
if request.user.has_perm('customer_details.view_customerdetail'):
data = CustomerDetailModel.get_object(ca_number)
serializer = CustomerDetailSerializer(data)
return Response(serializer.data)
else:
return Response('Denied_msg', status=status.HTTP_403_FORBIDDEN)
def get(self, request, ca_number, format=None):#get single customer
try:
return CustomerDetailModel.objects.get(pk=ca_number)
except CustomerDetailModel.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
def post(self, request, format=None):
serializer = CustomerDetailSerializer(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):
try:
data = self.get_object(pk)
serializer = CustomerDetailSerializer(data, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
except CustomerDetailModel.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
def delete(self, request, pk, format=None):
try:
data = self.get_object(pk)
data.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
except CustomerDetailModel.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
customer_details/urls.py:
from django.contrib import admin
from django.urls import path
from . import views
from .views import CustomerDetailView
urlpatterns = [
path('ca_number/',views.CustomerDetailView.as_view()),
]

Related

PUT request doesn't update - Django Rest Framework

I'm trying to build a todos app using django-rest-framework and when I send PUT request to change the content of the task, the content is still the same. It seems that the serializer.save() is not working as I expected.
Here are the code:
views.py
from rest_framework.response import Response
from rest_framework.decorators import api_view
from .models import Note
from .serializers import NoteSerializer
#api_view(['PUT'])
def updateNote(request, pk):
note = Note.objects.get(id=pk)
serializer = NoteSerializer(instance=note, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
models.py
from django.db import models
class Note(models.Model):
body = models.TextField(null=True, blank=True)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.body[0:50]
serializers.py
from rest_framework.serializers import ModelSerializer
from .models import Note
class NoteSerializer(ModelSerializer):
class Meta:
model = Note
fields = '__all__'
I'm learning django so this is kinda new to me. I had searched for this problem but I'm kinda new to django so I don't understand these answers much. Any help would be appreciated.
#api_view(['PUT'])
def updateNote(request, self, pk):
note = get_object_or_404(Note.objects.all(), pk=pk)
serializer = NoteSerializer(instance=note, data=request.data, partial=True)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)

Django Rest API Pagination not limiting number of objects

i followed the documentation but i still get the full list of objects not limited
views.py
from rest_framework.pagination import (LimitOffsetPagination,PageNumberPagination)
class PostView(generics.ListAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer
pagination_class = PageNumberPagination
def list(self, request, *args, **kwargs):
self.object_list = self.filter_queryset(self.get_queryset())
serializer = self.get_serializer(self.object_list, many=True)
return Response(serializer.data)
settings.py
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 2
}
By implementing the list method yourself, the pagination is no longer applied. Indeed, the list method for a ListAPIView is implemented as [GitHub]:
def list(self, request, *args, **kwargs):
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)
But you thus do not need to implement the list method yourself. Your view can look like:
from rest_framework.pagination import (LimitOffsetPagination,PageNumberPagination)
class PostView(generics.ListAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer
pagination_class = PageNumberPagination
# no list method

Ordering (sorting) from URL in django-rest-framework-filters with ComplexFilterBackend

Are there ability to Ordering result with djangorestframework-filters ComplexFilterBackend from URL?
DRF OrderingFilter is not worked with standart examples for djangorestframework-filters v.1.0.0.dev2.
My code with default order_by in query_set:
Filter class:
from models import Template
class TemplateFilter(filters.FilterSet):
class Meta:
model = Template
fields = {
'id': '__all__',
'status': '__all__',
'name' : '__all__',
'parent_id' : '__all__',
}
View:
from serializers import TemplateListSerializer
from models import Template
from filters import TemplateFilter
class TemplateListView(ListCreateAPIView):
filter_class = TemplateFilter
def get(self, request, *args, **kwargs):
self.queryset = Template.objects.all().order_by('-created')
self.serializer_class = TemplateListSerializer
return self.list(request, *args, **kwargs)
How I can to change this code for ordering (sort) response from URL Request?
I want to see record with parent_id=guid first.
My input url for Django:
GET /api/templates/?filters=(parent_id__isnull%3DTrue)%7C(parent_id%3Dguid)%26(ordering%3Dparent_id)&page=1
Decoded:
/api/templates/?filters=(parent_id__isnull=True)|(parent_id=guid)&(ordering=parent_id)&page=1
Answer - mandatory set two backend filters:
First - for search, ComplexFilterBackend
Second - for ordering, OrderingFilter
from serializers import TemplateListSerializer
from models import Template
from filters import TemplateFilter
from rest_framework import filters
from rest_framework_filters.backends import ComplexFilterBackend
class TemplateListView(ListCreateAPIView):
filter_class = TemplateFilter
def get(self, request, *args, **kwargs):
self.queryset = Template.objects.all()
self.serializer_class = TemplateListSerializer
self.filter_backends = [ComplexFilterBackend, filters.OrderingFilter]
self.ordering_fields = ['parent_id', 'name']
self.ordering = ['parent_id']
return self.list(request, *args, **kwargs)

How to update records in a Postgres table with Django rest framework

I have basic django app that returns data from Postgres tables in an AWS RDS instance.
I have a few endpoint which relate to few tables in the RDS.
What I want to do is update records in table. If the record exists it should be updated, if it does not exist then nothing should happen Orit should throw an error.
This is my models.py file -
from django.db import models
class Campaigns(models.Model):
id_campaign = models.CharField(max_length=250, blank=True, null=True)
status = models.CharField(max_length=250, blank=True, null=True)
id_taste_cluster = models.CharField(max_length=250, blank=True, null=True)
I want to update the status field in this table where status = ' '.
This is my serialiser file -
from rest_framework import serializers
from .models import Campaigns
class Campaigns_1_Serializer(serializers.ModelSerializer):
class Meta:
model = Campaigns
fields = ('id_campaign', 'status', 'id_taste_cluster')
This is my views file -
from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework import generics
from .models import Campaigns
from .serializers import Campaigns_1_Serializer
class UpdateView(viewsets.ModelViewSet):
def update(self, request, *args, **kwargs):
data = request.DATA
queryset = Campaigns.objects.filter(status='')
serializer = Campaigns_1_Serializer(queryset, data=data, many=True)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
I want to give the users the option to update only those campaigns for which the status is ' '(blank).
How can I do that ?
You need to change your update method :
#your imports
from rest_framework import serializers
class YourModelViewset(ModelViewSet):
#your code
def update(self, request, *args, **kwargs):
instance = self.get_object()
# checks if the object staus is empty
If object.status == "" or object.status is None :
raise serializers.ValidationError("your error message")
return super(YourModelViewset, self).update(request, *args, **kwargs)

Django Filter Backend not working in restful api in django

I am trying to use django-filters in have search queries in url using params
view.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.filters import SearchFilter
from .models import RecruiterRegister
from .serializers import RecruiterRegisterSerializer
# from rest_framework import filters
from rest_framework import generics
class RecruiterRegisterList(APIView):
queryset=RecruiterRegister.objects.all()
filter_backends = (DjangoFilterBackend,SearchFilter ,)
filter_fields = ('email','password')
search_fields = ('email','password')
def get(self, request, format=None):
recruiterRegisters = RecruiterRegister.objects.all()
# self.filter_backends = (DjangoFilterBackend,)
# self.filter_fields = ('password', )
serializer = RecruiterRegisterSerializer(recruiterRegisters, many=True)
return Response(serializer.data)
def post(self, request, format=None):
serializer = RecruiterRegisterSerializer(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 delete(self, request, pk, format=None):
recruiterRegisters = self.get_object()
recruiterRegisters.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
but I am not able to get filtered data. All the api data appears.
url sample
http://127.0.0.1:8000/recruiterRegister/?password=random2
edited RecruiterRegisterList class:
class RecruiterRegisterList(generics.ListAPIView):
queryset=RecruiterRegister.objects.all()
serializer_class = RecruiterRegisterSerializer
filter_backends = (DjangoFilterBackend,)
filter_fields=('email','password')
# search_fields = ('email','password')
def list(self, request ):
queryset = self.get_queryset()
serializer = RecruiterRegisterSerializer(queryset, many=True)
return Response(serializer.data)
First question is - why would you ever want to filter or search by password? that is a very unhealthy and unsecure design. Passwords are not stored in their raw formats but hashed so the filters will never hit anyway
Now, even if you really wanted to do that, filtering using filter_backends is implemented in the GenericAPIView and not available in APIView so you may want to use the ListAPIview from rest_framework.generics instead.
Lastly, even if you used the ListAPIView, it still wouldn't work because you're overriding the get method and not calling self.filter_queryset().
Use the ListAPIView and use the already implemented list() method and it will work
I'm adding only the line bellow & working fine:
filter_backends = self.filter_queryset(queryset)
And your code like:
class RecruiterRegisterList(generics.ListAPIView):
queryset=RecruiterRegister.objects.all()
serializer_class = RecruiterRegisterSerializer
filter_backends = (DjangoFilterBackend,)
filter_fields=('email','password')
search_fields = ('email','password')
def list(self, request ):
queryset = self.get_queryset()
filter_backends = self.filter_queryset(queryset)
serializer = RecruiterRegisterSerializer(filter_backends, many=True)
return Response(serializer.data)

Resources