Searching is not working in django rest_framework - django-rest-framework

Searching is not working in the django rest framework. searching for the approved status of leave applied by a particular employee. But the filtering/ searching/ sorting is properly working in the admin user. but not in the employee side.
Views.py
class LeaveList(APIView):
authentication_classes = [SessionAuthentication, BasicAuthentication, TokenAuthentication]
permission_classes = [IsAuthenticated]
filter_backends = [DjangoFilterBackend,SearchFilter,OrderingFilter]
ordering_fields = ['apply_date','number_of_days','status']
search_fields = ['status']
filter_fields = ['status']
def get(self, request, format=None):
employee = request.user
filter_backends = [DjangoFilterBackend,SearchFilter,OrderingFilter]
search_fields = ['status']
queryset = LeaveApplicationModel.objects.filter(employee_id=employee.id)
serializer_class = LeaveApplicationsListSerializer(queryset, many=True)
return Response(data=serializer_class.data)
Serializers.py
class LeaveApplicationsListSerializer(serializers.ModelSerializer):
class Meta:
model = LeaveApplicationModel
exclude = ['id', 'employee']
postman request
postman request
expecting

You're not using the search_filters anywhere. GenericAPIView or any class that subclasses it, e.g. ListAPIView, will use it automatically. It's in the docs.
If I were you, I'd rather subclass ListAPIView and set the relevant available attributes correctly. You can overwrite get_queryset to filter for the employee:
class LeaveList(ListAPIView):
authentication_classes = [SessionAuthentication, BasicAuthentication, TokenAuthentication]
permission_classes = [IsAuthenticated]
filter_backends = [DjangoFilterBackend,SearchFilter,OrderingFilter]
ordering_fields = ['apply_date','number_of_days','status']
search_fields = ['status']
filter_fields = ['status']
serializer_class = LeaveApplicationsListSerializer
def get_queryset(self):
employee = self.request.user
return LeaveApplicationModel.objects.filter(employee_id=employee.id)

Related

How to retrieve multiple slugs as url parameters with Django REST Framework DRF RetrieveAPIView?

I am new to DRF. I am very interested in application of generic views. I want to rewrite the following code with generic DRF view RetrieveAPIView:
views.py
class ProductDetail(APIView):
def get_object(self, category_slug, product_slug):
try:
return Product.objects.filter(category__slug=category_slug).get(slug=product_slug)
except Product.DoesNotExist:
raise Http404
def get(self, request, category_slug, product_slug, format=None):
product = self.get_object(category_slug, product_slug)
serializer = ProductSerializer(product)
return Response(serializer.data)
urls.py
urlpatterns = [
path('products/<slug:category_slug>/<slug:product_slug>/',
ProductDetail.as_view())
]
models.py
class Category(models.Model):
name = models.CharField(max_length=255)
slug = models.SlugField()
class Meta:
ordering = ('name',)
def __str__(self):
return self.name
def get_absolute_url(self):
return f'/{self.slug}/'
class Product(models.Model):
category = models.ForeignKey(
Category, related_name='products', on_delete=models.CASCADE)
name = models.CharField(max_length=255)
slug = models.SlugField()
description = models.TextField(blank=True, null=True)
price = models.DecimalField(max_digits=6, decimal_places=2)
image = models.ImageField(upload_to='uploads/', blank=True, null=True)
thumbnail = models.ImageField(upload_to='uploads/', blank=True, null=True)
date_added = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ('-date_added',)
def __str__(self):
return self.name
def get_absolute_url(self):
return f'{self.category.slug}/{self.slug}/'
How can I use RetrieveAPIView instead of above APIView?
I tried to add a custom mixin, did not help:
class MultipleFieldLookupMixin:
def get_object(self):
queryset = self.get_queryset() # Get the base queryset
queryset = self.filter_queryset(queryset) # Apply any filter backends
multi_filter = {field: self.kwargs[field] for field in self.lookup_fields}
obj = get_object_or_404(queryset, **multi_filter) # Lookup the object
self.check_object_permissions(self.request, obj)
return obj
class ProductDetail(MultipleFieldLookupMixin, RetrieveAPIView):
queryset = Product.objects.filter(category__slug=category_slug).get(slug=product_slug)
serializer = ProductSerializer
lookup_fields = ['category_slug', 'product_slug']
Does not work.

Filter in Django Rest Framework

I'm new in DRF: ¿Can I create a filter in a function in Django Rest Framework, not created it in a Class, for use in a view? I'm trying a filter for search by: document and document_type.
Ty
My code:
#model
class Account(models.Model):
'''Modelo para la gestión de cuentas'''
document_type = models.CharField('Tipo documento', null=True, max_length=20, choices=DOCUMENT_TYPE)
document = models.CharField('Documento',null=True, max_length=18)
first_name = models.CharField('Nombres / razón social',null=True, max_length=100)
last_name = models.CharField('Apellidos', null=True, max_length=100)
phone = models.CharField('Teléfono fijo', max_length=7, null=True, blank=True)
cellphone = models.CharField('Celular', max_length=10, null=True, blank=True)
email = models.EmailField('Correo', max_length=100, null=True, blank=True )
address = models.CharField('Dirección', max_length=70, null=True, blank=True)
gender = models.CharField('Genero',null=True, max_length=1, choices=GENDER_TYPE)
affiliate_type = models.CharField('Tipo de afiliado',null=True, max_length=12, choices=AFFILIATE_TYPE)```
#view
```class AccountList(APIView):
"""
List all accounts, or create a new account....
"""
def get(self, request, format=None):
account = Account.objects.all()
serializer = AccountSerializer(account, many=True)
filter_class = AccountFilter
filter_backends = [filters.SearchFilter]
return Response({'data':serializer.data},status=status.HTTP_200_OK)
def post(self, request, format=None):
serializer = AccountSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response({'Message':'Registro creado exitosamente'}, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)```
#filter
class AccountFilter(django_filters.rest_framework.FilterSet):
class Meta:
model = Account
fields = {
'document': ['exact'],
'document_type': ['exact']
}
ordering_fields = ('document')
You can use self.filter_queryset(queryset) to filter queryset using filter class.
class AccountList(APIView):
def get(self, request, format=None):
self.filter_class = AccountFilter
self.filter_backends = [filters.SearchFilter]
account_qs = Account.objects.all()
account = self.filter_queryset(account_qs)
serializer = AccountSerializer(account, many=True)
return Response({'data':serializer.data},status=status.HTTP_200_OK)

Why my delete method is not working properly?

I have troubles with my code in deleting a specific loan_id(primary key). My post method works good but my delete method doesn´t. Here's my code:
views.py:
class SolicitudPrestamoViewSet(viewsets.mixins.CreateModelMixin,viewsets.mixins.DestroyModelMixin,viewsets.GenericViewSet):
permission_classes = [IsAdminUser]
serializer_class = SucursalSerializer
queryset = Prestamo.objects.all()
lookup_field = 'loan_id'
def get(self, request, format=None,):
serializer = SucursalSerializer()
return Response(serializer.data)
def delete(self, request, loan_id, format=None):
object = self.get_object(loan_id)
object.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
models.py:
class Prestamo(models.Model):
loan_id = models.AutoField(primary_key=True)
loan_type = models.CharField(max_length=20,
choices = [('PERSONAL', 'PERSONAL'), ('HIPOTECARIO', 'HIPOTECARIO'), ('PRENDARIO', 'PRENDARIO')])
loan_date = models.DateField()
loan_total = models.IntegerField()
customer_id = models.IntegerField()
class Meta:
db_table = 'prestamo'
In viewset you should use destroy method to handle DELETE requests:
class SolicitudPrestamoViewSet(viewsets.mixins.CreateModelMixin,viewsets.mixins.DestroyModelMixin,viewsets.GenericViewSet):
permission_classes = [IsAdminUser]
serializer_class = SucursalSerializer
queryset = Prestamo.objects.all()
lookup_field = 'loan_id'
def destroy(self, request, loan_id):
object = self.get_object(loan_id)
object.delete()
return Response(status=status.HTTP_204_NO_CONTENT)

"How to Add "Nested URL in DRF ,dynamic model viewset"

* i have * router.register(r'reseller/', views.UserViewSet)
and router.register(r'one/', views.OneLViewSet)
I want to make nested url like 'reseller/ or {pk}/one/
But i'm failed.
I tried adding DynamicRelationField to User Model but not worked.
my user_model
phone = models.CharField(_('phone number'), max_length=30, blank=True)
address = models.CharField(_('reseller address'), max_length=220, blank=True)
OneL model
id = models.AutoField(_('lottery id'), unique=False, primary_key=True, auto_created=True,)
lno = models.CharField(_('1000ks lottery'), max_length=8, unique=True)
name = models.CharField(_('customer name'), max_length=100, )
reseller = models.ForeignKey('lotto_app.User', on_delete=models.CASCADE)
user_serializer
class UserSerializer(serializers.DynamicModelSerializer):
class Meta:
model = User
fields = ('id', 'username', 'email', 'phone', 'address', )
oneL serializer
class OneLSerializer(serializers.DynamicModelSerializer):
reseller = fields.DynamicField(source='reseller.username', read_only=True)
class Meta:
model = OneL
fields = (
'id', 'lno', 'name', 'reseller', 'phone', 'address', 'nth', 'is_winner', 'prize_details', 'created_at',
'updated_at')
user dynamicviewset
class UserViewSet(DynamicModelViewSet):
permission_classes = (IsAdmin, IsAuthenticated)
model = User
queryset = User.objects.all()
serializer_class = UserSerializer
OneLviewSet
class OneLViewSet(DynamicModelViewSet):
permission_classes = (IsAuthenticated, IsOwner)
model = OneL
queryset = OneL.objects.all()
serializer_class = OneLSerializer
def create(self, request, *args, **kwargs):
serializer = OneLSerializer(data=request.data)
if serializer.is_valid():
serializer.save(reseller=request.user)
return Response(serializer.data)
def list(self, request, *args, **kwargs):
queryset = OneL.objects.filter(reseller=request.user)
serializer = OneLSerializer(queryset, many=True)
return Response(serializer.data)
I want to change this.url
router.register(r'reseller', views.UserViewSet)
router.register(r'one', views.OneLViewSet)
urlpatterns = [
path('api/saledatas/', include(router.urls))
]
TO THIS
router.register(r'reseller', views.UserViewSet)
router.register(r'reseller/{pk}/one', views.OneLViewSet) #or <int:pk>
urlpatterns = [
path('api/saledatas/', include(router.urls))
]
After change
error-- "Request URL: http://localhost:8000/api/saledatas/reseller/1/one/" Not Found!
And How to make http://localhost:8000/api/saledatas/reseller/1/one/ to be work.
create action in Userviewset
#action(detail=True, methods=["get"])
def one(self, request):
''' to get instance just do get_object() it'll give reseller instance '''
user = self.get_object()
ones = user.onel_set.all()
''' now you can work on one '''

How to Add filter Backends in when you override list?

If I override list, filter backends is not working. How to apply my filter if I override list definition?
class CircuitViewSet(viewsets.ModelViewSet):
queryset = Circuit.objects.all()
serializer_class = CircuitSerializer
filter_backends = (filters.DjangoFilterBackend, filters.OrderingFilter,)
filter_class = CircuitFilter
def list(self, request):
queryset = Circuit.objects.all()
serializer = CircuitSerializer(queryset, many=True, context={'request': request})
return Response(serializer.data)
class CircuitViewSet(viewsets.ModelViewSet):
queryset = Circuit.objects.all()
serializer_class = CircuitSerializer
filter_backends = (filters.DjangoFilterBackend, filters.OrderingFilter,)
filter_class = CircuitFilter
def list(self, request):
# with filter
queryset = self.filter_queryset(self.get_queryset())
# pagination
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)
I have faced this problem before. In my example, I just removed filter_backends = (filters.DjangoFilterBackend, filters.OrderingFilter,) part and filtering started to work.

Resources