Skip to main content

PyPI version Python Development Status Maintenance PyPI License


DRF Easy CRUD

Enterprise-grade utility library for simplifying CRUD operations in Django REST Framework. Provides powerful filtering, pagination, and standardized CRUD methods to accelerate API development.


Installation

uv add drf-easy-crud

Features

  • 🔧 Simplified CRUD Operations: Static utility methods for GET, POST, PUT, PATCH, and DELETE operations
  • 🔍 Advanced Filtering: Wildcard pattern matching for text fields, comparison operators for numeric fields
  • 📄 Built-in Pagination: Standard pagination with configurable page sizes
  • 🔗 ForeignKey Support: Filter across related models using Django's double-underscore lookup syntax
  • 🛡️ Enterprise-Grade Error Handling: Comprehensive error handling with detailed logging
  • 📊 Type-Safe: Full type hints for better IDE support and code reliability
  • ⚡ Performance Optimized: Efficient queryset handling with optional hooks for customization

Quick Start

Basic Usage

from rest_framework import viewsets
from rest_framework.request import Request
from rest_framework.response import Response

from drf_easy_crud import CRUDUtils
from myapp.models import MyModel
from myapp.serializers import MyModelSerializer


class MyModelViewSet(viewsets.ViewSet):
    """Example ViewSet using CRUDUtils."""

    def get(self, request: Request, pk: int | None = None) -> Response:
        """List all instances or retrieve a single one by pk."""
        return CRUDUtils.get(
            request=request,
            queryset=MyModel,
            serializer_class=MyModelSerializer,
            pk=pk,
        )

    def post(self, request: Request) -> Response:
        """Create a new instance."""
        return CRUDUtils.post(
            request=request,
            serializer_class=MyModelSerializer,
        )

    def put(self, request: Request, pk: int) -> Response:
        """Full update of an instance."""
        return CRUDUtils.put(
            request=request,
            queryset=MyModel,
            serializer_class=MyModelSerializer,
            pk=pk,
        )

    def patch(self, request: Request, pk: int) -> Response:
        """Partial update of an instance."""
        return CRUDUtils.patch(
            request=request,
            queryset=MyModel,
            serializer_class=MyModelSerializer,
            pk=pk,
        )

    def delete(self, request: Request, pk: int) -> Response:
        """Delete an instance."""
        return CRUDUtils.delete(
            request=request,
            queryset=MyModel,
            pk=pk,
        )

Advanced Features

Pre-scoped Querysets

Pass a pre-filtered queryset instead of a model class for full control:

def list(self, request: Request) -> Response:
    """List only active instances belonging to the current user."""
    return CRUDUtils.get(
        request=request,
        queryset=MyModel.objects.filter(is_active=True, owner=request.user),
        serializer_class=MyModelSerializer,
    )

Custom Pagination

Use your own pagination class:

from drf_easy_crud import CRUDUtils, StandardResultsSetPagination
from rest_framework.pagination import PageNumberPagination


class CustomPagination(PageNumberPagination):
    page_size = 50
    max_page_size = 200


def list(self, request: Request) -> Response:
    return CRUDUtils.get(
        request=request,
        queryset=MyModel,
        serializer_class=MyModelSerializer,
        pagination_class=CustomPagination,
    )

Custom Ordering

Specify default ordering for list endpoints:

def list(self, request: Request) -> Response:
    return CRUDUtils.get(
        request=request,
        queryset=MyModel,
        serializer_class=MyModelSerializer,
        ordering_field="-created_at",  # Newest first
    )

Filtering

The library provides powerful filtering capabilities through FilterUtils:

Text Field Wildcard Patterns

Pattern Description Example Matches
field=value* Starts with ?name=test* "test", "test123", "testing"
field=*value Ends with ?name=*test "mytest", "123test"
field=*value* Contains ?name=*test* "test", "mytest", "testing"
field=va*ue Middle wildcard ?name=t*t "test", "tart", "t123t"
field=value Exact match ?name=test "test" (case-insensitive)

Number Field Comparison Operators

Pattern Description Example Matches
field=value Exact match ?age=25 Exactly 25
field=>=value Greater than or equal ?age=>=25 25, 26, 27, ...
field=<=value Less than or equal ?age=<=100 ..., 98, 99, 100
field=>value Greater than ?age=>25 26, 27, 28, ...
field=<value Less than ?age=<25 ..., 23, 24

ForeignKey Lookups

Filter by related model fields using double underscores:

# Filter by related model's text field
GET /api/products/?category__name=electronics*

# Filter by related model's number field
GET /api/products/?category__priority=>=5

# Nested ForeignKey lookup
GET /api/orders/?customer__company__name=acme*

Filtering Examples

# Search by name starting with "test"
GET /api/mymodel/?name=test*

# Search by name containing "important"
GET /api/mymodel/?name=*important*

# Filter by age >= 18
GET /api/mymodel/?age=>=18

# Filter by age between 18 and 30
GET /api/mymodel/?age=18-30

# Multiple filters combined
GET /api/mymodel/?name=test*&age=>=18&status=active

# ForeignKey lookup
GET /api/mymodel/?category__name=electronics*

Pagination

Results are paginated by default (20 items per page, max 100).

Pagination Parameters

  • page - Page number (default: 1)
  • page_size - Items per page (default: 20, max: 100)

Paginated Response Format

{
  "count": 150,
  "next": "http://example.com/api/mymodel/?page=2",
  "previous": null,
  "results": [
    {
      "id": 1,
      "name": "Item 1",
      ...
    },
    ...
  ]
}

🤝 Contributing

If you have a helpful tool, pattern, or improvement to suggest: Fork the repo
Create a new branch
Submit a pull request
I welcome additions that promote clean, productive, and maintainable development.


🙏 Thanks

Thanks for exploring this repository!
Happy coding!

Metadata

Release files for drf-easy-crud 2.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for drf-easy-crud 2.1.1
File Size Uploaded
drf_easy_crud-2.1.1.tar.gz 18.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for drf-easy-crud 2.1.1
File Interpreter ABI Platform
drf_easy_crud-2.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 37.4 kB

Release files / drf_easy_crud-2.1.1.tar.gz

Download URL drf_easy_crud-2.1.1.tar.gz
Size 18.0 kB
Tags Source
SHA-256 checksum
How to use checksums
3af6d1f6749d50bba72fad0f1c0b9fcea1c9eda98273d162519b22c27f241e5e
BLAKE2b-256 checksum
How to use checksums
abb080be273d2321ac021cae8e25acd662e12024f87bb7dac2f55baf2f940162
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.12

Release files / drf_easy_crud-2.1.1-py3-none-any.whl

Download URL drf_easy_crud-2.1.1-py3-none-any.whl
Size 19.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bc56707960a0a980ddd3cdfebc6d8521d9d39b460cd95c662d907179b7e9fbea
BLAKE2b-256 checksum
How to use checksums
e4849935b123028a22a532eaad2cda72b02ae0b0a75f605672ebbf67907dcd77
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.12

Release history Release notifications | RSS feed

This release

2.1.1 This release

2 release files

2.1.0

2 release files

2.0.0

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page