This is an example Django app that demonstrates the architecture pattern used in this project. It implements a simple "Post" model with full CRUD operations.
The application follows a layered architecture with clear separation of concerns:
- Contains Django ORM models
- Defines database structure and relationships
- Example:
Postmodel with title, content, user relationship, and timestamps
- Handles all database queries and data access
- Provides abstraction over Django ORM
- Methods:
get_posts_for_user(),get_post_by_id(),create_post(),update_post(),delete_post()
- Contains business logic
- Orchestrates between repositories and views
- Handles validation, authorization, and data transformation
- Uses DTOs for input/output
- DTOs (
dtos/): Pydantic models for request/response validationCreatePostDto: For creating postsUpdatePostDto: For updating postsPostResponseDto: For API responses
- Views (
views/): REST API endpoints using Django REST FrameworkPostListView: List all posts for authenticated userPostCreateView: Create a new postPostRetrieveView: Get a specific postPostUpdateView: Update a post (PUT/PATCH)PostDeleteView: Delete a post
- URLs (
urls.py): URL routing configuration
- Custom exception classes
- Provides meaningful error messages and HTTP status codes
- Examples:
PostNotFoundError,PostUnauthorizedAccessError
- Comprehensive test coverage using pytest
- Uses model_bakery for test data generation
- Test files:
test_models.py: Model validation and behaviortest_services.py: Business logic and authorizationtest_v1_views.py: API endpoints and integration
conftest.py: Shared pytest fixtures
- Services are injected into views using
dependency_injector - Configured in
ApplicationContainer - Example:
@inject def __init__( self, post_service: PostService = Provide[ApplicationContainer.services.post_service], **kwargs: Any, ) -> None:
- Uses
UserRequirementMixinfor user authentication - Services check ownership before allowing operations
- Only post owners can update or delete their posts
- Pydantic DTOs for request/response validation
- Clear separation between API layer and domain models
- Type-safe data transformation
- Custom exception hierarchy
- HTTP status codes automatically mapped
- Consistent error responses
example/
├── __init__.py
├── apps.py # Django app configuration
├── admin.py # Django admin configuration
├── pagination.py # REST framework pagination
├── models/
│ ├── __init__.py
│ └── post.py # Post model
├── repositories/
│ ├── __init__.py
│ └── post_repository.py # Data access layer
├── services/
│ ├── __init__.py
│ └── post_service.py # Business logic layer
├── api/
│ └── v1/
│ ├── __init__.py
│ ├── urls.py # API routes
│ ├── dtos/
│ │ ├── __init__.py
│ │ └── post_dto.py # Request/response DTOs
│ └── views/
│ ├── __init__.py
│ └── post_views.py # API endpoints
├── exceptions/
│ ├── __init__.py
│ └── post_exceptions.py # Custom exceptions
├── tests/
│ ├── __init__.py
│ ├── conftest.py # Test fixtures
│ ├── test_models.py # Model tests
│ ├── test_services.py # Service tests
│ └── test_v1_views.py # API tests
└── migrations/
└── __init__.py
GET /api/v1/example/list- List all posts for authenticated userPOST /api/v1/example/create- Create a new postGET /api/v1/example/list/<id>- Get a specific postPUT/PATCH /api/v1/example/<id>/update- Update a postDELETE /api/v1/example/<id>/delete- Delete a post
Run tests with:
make testRun tests for this app only:
pytest app/example/tests/ -vTo create a similar feature in your own app:
- Create the model in
models/your_model.py - Create the repository in
repositories/your_repository.py - Create the service in
services/your_service.py - Create DTOs in
api/v1/dtos/your_dto.py - Create views in
api/v1/views/your_views.py - Configure URLs in
api/v1/urls.py - Create custom exceptions in
exceptions/your_exceptions.py - Write tests in
tests/ - Register in dependency container (see
core/dependency_injector/containers.py)
This pattern uses:
- Django & Django REST Framework
- Pydantic for DTOs
- dependency-injector for DI
- pytest & model_bakery for testing