Package: drf-scrud
DRF SCRUD ViewsetDRF SCRUD (emphasizes on the S, you'll discover why) Viewset is a lightweight Django package built on top of django-rest-framework. It delivers a highly abstracted global viewset thats provides common CRUD operations methods including advanced search and pagination.FeaturesCreate, Read, Update and Delete ready-to-go methods for viewsetsFileUploadParser enabled for create and edit methods to allow uploading files and imagesPowerful search feature (all its greatness describedbellow)Toggle status of instances (ifis_activefield on model)Paginated responsesInstallpipinstalldrf-scrudQuick StartAddscrudto yourINSTALLED_APPSlike this:INSTALLED_APPS=[...'scrud',]```Use inviews.py:fromscrudimportScrudViewsetfrom.importmodels,serializersclassBookViewset(ScrudViewset)# Override the default permissions by action if needed. Default is AllowAny for all actions.permission_classes_by_action={'create':[IsAuthenticated],'list':[IsAuthenticated],'get':[IsAuthenticated],'edit':[IsAuthenticated],'delete':[IsAdminUser],'active':[IsAdminUser],'desactive':[IsAdminUser],'inactives':[IsAdminUser],'search':[IsAuthenticated]}def__init__(self):super().__init__(models.Book,serializers.BookSerializer,self.permission_classes_by_action)When defining your Viewset this way, BookViewset inherit these methods:list,create,get,edit,delete,activate,deactivate,searchThen, inurls.pyyou can set:path('book/',include([path('',views.BookViewset.as_view({'get':'list','post':'create'})),path('<int:pk>/',views.BookViewset.as_view({'get':'get'})),path('<int:pk>/edit/',views.BookViewset.as_view({'put':'edit'})),path('<int:pk>/delete/',views.BookViewset.as_view({'delete':'delete'})),path('search/',views.BookViewset.as_view({'get':'search'})),])),DRF SettingsThe returned json of all the endpoints are page number paginated, so you may need to set a defaultPAGE_SIZEinsettings.pyREST_FRAMEWORK={'DEFAULT_PAGINATION_CLASS':'rest_framework.pagination.PageNumberPagination','PAGE_SIZE':10}You are done ! All the endpoints should be working fine by now.Especialy for the 'inactives()' actionThis action make use of a customized manager that bindsactive_rows()andinactive_rows()to model.objects, likeBook.objects.inactive_rows()So if you intend to use this action, consider adding the manager in your models.py like this:fromscrud.managersimportTemporalQuerySetclassBookModel(models.Model):...objects=TemporalQuerySet()The Search ActionThis action implements advanced query filtering throught model instances to help you improve your API.https://YOUR_API_ENDPOINT/search/?field_name=valueThefield_namecan be any of the model field.Considering a model represented by this json{"id":1,"title":"The journey to Elixir","description":"Elixir is going to rule the world. You better watch out !","price":250,"currency":"USD","release_date":"2022-10-10","author":{"id":1,"firstName":"John","lastName":"Doe","city":{"id":5,"name":"Sydney","country":{"id":2,"name":"Australia"}}}}You can filter bytitle,descriptionand/or any other/search/?title="stuff"or/search/?title="elix"&description="world"&price=150&{and_so_on_to_infinity}String fields are double-quotedEven betterYou can lookup throughout related models/search/?author__city__country_name="Aus"Double underscore __ to reach related model name, and single _ to reach a fieldString field lookups are case insensitive and perform a like %% sql queryOverriding a methodYou can override any of the pre-built method.e.g adding decorator@extend_schema(parameters=[OpenApiParameter(name='title',required=False,location=OpenApiParameter.QUERY,),])defsearch(self,request):returnsuper().search(request)If you want to override the entire function, just write your function as usualdefsearch(self,request):# New code goes hereFeel free to open issues or to pull request. Contributors are welcome.© Shuruzer.