class ProductViewSet(viewsets.ModelViewSet):
authentication_classes = (TokenAuthentication)
permission_classes = [IsAdminUser]
queryset = ProductInfo.objects.all().order_by('-id')
serializer_class = ProductSerializer
filter_backends = (filters.SearchFilter,)
search_fields = ['title','code','owner__username']
I try to use token authentication for authorizating this class view. and I get an error. plz help me.
You have to define the authentication_classes as an iterable, so you need to add the ,:
authentication_classes = (TokenAuthentication, )
or just define it as a list:
authentication_classes = [TokenAuthentication]
Related
I'm trying to retrieve the first record in a table using the endpoint below (please suggest if there's a more sensible URL convention).
http://127.0.0.1:8000/api/review/?first
The view I have works, but I'm hoping to refactor it because it smells.
class ReviewViewSet(ModelViewSet):
filter_backends = (DjangoFilterBackend, OrderingFilter)
serializer_class = ReviewSerializer
permission_classes = [permissions.IsAuthenticated]
def get_queryset(self):
first = self.request.query_params.get('first')
queryset = RecordReview.objects.all()
if first is not None:
id_list = queryset.values_list('id')
first_item = id_list.order_by('id').first()
first_id = first_item[0]
queryset = queryset.filter(id=first_id)
return queryset
When I attempted to filter the queryset directly, I got errors like:
TypeError: object of type 'RecordReview' has no len()
The error comes from this line :
first_id = first_item[0]
This is because first_item is already a RecordReview, as it was retrieved using first()
You can simplify get_queryset as follows though :
class ReviewViewSet(ModelViewSet):
filter_backends = (DjangoFilterBackend, OrderingFilter)
serializer_class = ReviewSerializer
permission_classes = [permissions.IsAuthenticated]
def get_queryset(self):
first = self.request.query_params.get('first')
queryset = RecordReview.objects.all()
if first is not None:
queryset = queryset.order_by('id')[:1]
return queryset
I created the following view in my REST API. It works as intended, the only issue I still have is that if NO search term is defined, the first 15 results from my database are returned (without any filtering). Is there are a way to return User.objects.none() as long no ?search input is given?
class UserRetrieve(generics.ListAPIView):
permission_classes = [RetoolPermissions]
queryset = User.objects.all()
serializer_class = UserSerializer
filter_backends = [filters.SearchFilter]
search_fields = ["email", "first_name", "last_name"]
refer to https://www.django-rest-framework.org/api-guide/generic-views/#genericapiview
queryset - The queryset that should be used for returning objects from this view. Typically, you must either set this attribute, or override the get_queryset() method.
try this code below
class UserRetrieve(generics.ListAPIView):
permission_classes = [RetoolPermissions]
# queryset = User.objects.all()
serializer_class = UserSerializer
filter_backends = [filters.SearchFilter]
search_fields = ["email", "first_name", "last_name"]
def get_queryset(self):
# Put your logic here ..
term = self.request.GET.get('search') # get the arg
qs = super(UserRetrieve, self).get_queryset()
return qs.filter(name=term) if term else None
see this thread : https://stackoverflow.com/a/21366037/12368419
i want to select all data with the same item in Product table.
class ProductViews(viewsets.ModelViewSet):
permission_classes =(permissions.IsAuthenticated, permissions.IsAdminUser)
queryset = Generate.objects.all()
serializer_class = GenerateSerializer
Here is my modelViewSet. Any help ?
I found the solution with django-filter
class ProductViews(viewsets.ModelViewSet):
permission_classes =(permissions.IsAuthenticated, permissions.IsAdminUser)
queryset = Product.objects.all()
serializer_class = ProductSerializer
filter_backends = [DjangoFilterBackend]
filterset_fields = ['desination']
Now you can do : http://localhost.com/api/products/?desination=exemple
I want to create a subview (if this is the right term?) under a view that alters the query set for example
parent URL
mysite.com/api/sites
Child URL
mystic.com/apit/sites/open
and also each one of those URLS could be searched so
parent URL
mysite.com/api/sites/search=London
Child URL
mystic.com/api/sites/open/search=London
my parent View, serializer, and URL already exists
class SiteROView(viewsets.ReadOnlyModelViewSet):
queryset = Site.objects.all()
serializer_class = SiteSerializer
permission_classes = (IsAdminUser,)
filter_class = Site
filter_backends = (filters.SearchFilter,)
search_fields = ('location','postcode','state')
so I think I need to somehow add the suburl to that
class SiteROView(viewsets.ReadOnlyModelViewSet):
queryset = Site.objects.all()
serializer_class = SiteSerializer
permission_classes = (IsAdminUser,)
filter_class = Site
filter_backends = (filters.SearchFilter,)
search_fields = ('location','postcode','state')
def url_open:
queryset = Site.objects.filter(state='open')
Is this possible, and how would I achieve it?
Thanks
You can do that by using detail_route decorator
from rest_framework.response import Response
class SiteROView(viewsets.ReadOnlyModelViewSet):
..........
# your codes up here
#list_route(methods=['get'],url_path='open' permission_classes=[YourPermissionClass])
def open(self, request, *args, **kwargs):
# your rest of code and response
queryset = <your_filtered_queryset>
serializer = self.serializer_class(queryset, many=True)
return Response(data=serializer.data)
At first you see my 4 method class in view.py:
class ContactList(ListAPIView):
queryset = Contact.objects.all()
serializer_class = ContactSerializers
# This is delete method
class ContactDelete(DestroyAPIView):
queryset = Contact.objects.all()
serializer_class = ContactSerializers
lookup_field = 'pk'
#below is post method to create new contact
class ContactCreate(CreateAPIView):
queryset = Contact.objects.all()
serializer_class = ContactSerializers
#below is put and patch method to update contact
class ContactUpdate(UpdateAPIView):
queryset = Contact.objects.all()
serializer_class = ContactSerializers
lookup_field = 'pk'
I want ContactList and ContactCreate should be in one class
and ContactDelete and ContactUpdate should be in one class
i am not getting how to merge it, can anyone tell me how to do it?
Note: i dont want APIViewSet
DRF has already to classes for that purpose. You can check them here and here
from rest_framework.generics import ListCreateAPIView, RetrieveDestroyAPIView
class ContactCreateListAPIView(ListCreateAPIView):
queryset = Contact.objects.all()
serializer_class = ContactSerializers
class ContactRetrieveDeleteAPIView(RetrieveDestroyAPIView):
queryset = Contact.objects.all()
serializer_class = ContactSerializers
lookup_field = 'pk'
Hope this helps
# This is create and list method
class ContactListCreate(ListAPIView, CreateAPIView):
queryset = Contact.objects.all()
serializer_class = ContactSerializers
# This is delete and update method
class ContactDeleteUpdate(DestroyAPIView, UpdateAPIView):
queryset = Contact.objects.all()
serializer_class = ContactSerializers
You can remove lookup_field = 'pk' from the view, since DRF took pk as the default value.