Working directory structure for a Django-Python project used as an API backend only
I'm a newbie in Django Python and I need to create an API backend for a frontend done in React. I'm forced by the customer to use Django Python, no options on this!
The project is very simple: it needs to expose ~15 endpoints, use Django ORM to connect to a PostgreSQL database, and have basic business logic. I must have a minimum of 80% unit tests coverage of the code and expose a swagger UI.
My problem is to create a "standard", well-defined, wisely organized structure of the working directory structure as defined by the best practice.
In .NET I put my endpoints in the controllers, then I create the business logic with interfaces and the data layer where I have the model and the entities, so everything is all well organized and separated.
How can I achieve a similar organization in Django?
I've seen that some people use DRF (Django RESTful framework), is it good for my purpose? is it a best practice for projects like mine?
Django REST framework should work for your project. It supports the serialization, validation, authentication, and documentation (Swagger) needs for your ~15 endpoints that you are talking about.
Typical project Structure
my_project/
│
├── manage.py # Django's command-line utility
│
├── project_config/ # Project settings directory
│ ├── __init__.py
│ ├── settings.py # Project settings
│ ├── urls.py # Project-level URL routing
│ ├── asgi.py # ASGI config for deployment
│ └── wsgi.py # WSGI config for deployment
│
├── api/ # Main API app
│ ├── __init__.py
│ ├── urls.py # API-specific URL routing
│ ├── views/ # Your "controllers" in Django terms
│ │ ├── __init__.py
│ │ ├── user_views.py # User-related endpoints
│ │ ├── product_views.py # Product-related endpoints
│ │ └── ...
│ │
│ ├── serializers/ # Handle JSON conversion & validation
│ │ ├── __init__.py
│ │ ├── user_serializers.py
│ │ ├── product_serializers.py
│ │ └── ...
│ │
│ ├── models/ # Database models (ORM)
│ │ ├── __init__.py
│ │ ├── user.py
│ │ ├── product.py
│ │ └── ...
│ │
│ ├── services/ # Business logic layer
│ │ ├── __init__.py
│ │ ├── user_service.py
│ │ ├── product_service.py
│ │ └── ...
│ │
│ └── tests/ # Test directory
│ ├── __init__.py
│ ├── test_user_api.py
│ ├── test_product_api.py
│ └── ...
│
├── utils/ # Shared utilities and helpers
│ ├── __init__.py
│ ├── permissions.py # Custom permissions
│ ├── pagination.py # Custom pagination
│ └── ...
│
├── requirements.txt # Project dependencies
│
└── .env # Environment variables (not in version control)
This structure maps to your .NET terminology as follows.
Controllers
: In Django, these are called 'views' and live in theapi/views/ directory
.Business Logic
: Yourapi/services/
directory is where business logic lives.Data Layer:
The DjangoORM models
inapi/models/
handle your data layer.
Mapping to .NET Layers
.NET Layer | Django Equivalent |
---|---|
Controllers (API Endpoints) | api/views/ (Django Views) |
Business Logic (Services) | api/services/ |
Data Layer (Models) | api/models/ (Django ORM) |
Interfaces (Repositories, DTOs) | api/serializers/ (For DTOs), abstract base classes in utils/ |
Dependency Injection / Middleware | project_config/settings.py (for middleware), custom logic in utils/ |
Configuration / AppSettings | .env and project_config/settings.py |
Refer my blog that has steps once I made for my refrence for easy setup of Django API Backend Directory Structure. - Setting Up Your Django Project
Also a good refrence - https://plainenglish.io/blog/how-to-structure-your-django-project-a5d50333a644
Just in case: RESTful API Endpoint Naming Conventions
1. Use Lowercase Letters Use lowercase letters in all API URLs for consistency, ease of typing, and to minimize confusion in case-sensitive systems, which improves SEO and user experience. Example: '/api/v1/users', '/api/v3/orders'
2. Use Nouns, Avoid Verbs (CRUD Functions) Design APIs as resource-oriented, using nouns to represent resources (e.g., '/users', '/products') rather than verbs (e.g., '/getUsers', '/updateProducts'). Let HTTP methods (GET, POST, PUT, DELETE) define actions. Correct: '/users', '/products' Avoid: '/get-users', '/update-products'
3. Use Singular and Intuitive Names for URI Hierarchy Use singular nouns for document resource archetypes (e.g., a single entity) to create clear, concise, and SEO-friendly URLs that are easy for both developers/QAs and search engines to understand. Example: '/rest-api/v1/users', '/api/v1/orders' Be clear and descriptive in your naming. Avoid slang or abbreviations that may be unclear to others. Example: use 'order-history' instead of 'ord-hist' or 'prod-cat' to make it clear.
4. Use Forward Slash (/) to Indicate URI Hierarchy Organize your URIs using forward slashes to create a clear hierarchy (e.g., '/users', '/users/{id}', '/orders'). Avoid trailing slashes (e.g., should not be '/users/', should be '/users') to prevent ambiguity, ensure consistency, and avoid duplicate content issues in SEO. Example: '/users', '/users/123', '/orders'
5. Use Hyphens (-) to Separate Words for Readability Use hyphens to separate words in endpoint names for better readability and search engine optimization (e.g., '/users-profile', '/order-history'). Avoid underscores (_) and camelCase, as they are less readable and less SEO-friendly. Example: '/users-profile', '/order-history', '/product-category'
6. Use Query Parameters to Filter and Provide Details Use query parameters to filter, sort, or provide specific subsets of data from the server (e.g., '/products?category=electronics&sort=price'). These parameters can include sorting, filtering, and pagination to enhance flexibility. Represent complex filtering as query parameters (e.g., '/products?price>100&sort=desc'). Ensure special characters are URL-encoded for robustness. Example: '/products?category=electronics&sort=price', '/users?role=admin&limit=5'
7. Enable Filtering, Sorting, and Pagination Implement pagination using limit and offset or page parameters (e.g., '/products?limit=10&offset=20', '/products?page=1&limit=5') to manage large datasets and prevent overwhelming clients or servers. Enable filtering and sorting via query parameters (e.g., '/products?category=electronics&sort=brand'). Example: '/products?limit=10&offset=20', '/products?page=1&limit=5', '/users?role=admin&limit=5'
8. Avoid Using URL/URI Escape Characters Avoid characters like space (%20), $, &, <, >, [], |, ", ', ^ in your URIs. These characters can lead to confusion or be problematic in certain environments, so it's best to avoid them entirely in your endpoint paths.
9. Do Not Use File Extensions Avoid appending file extensions like .json, .xml, or .html to API routes. Use HTTP headers (Accept and Content-Type) for content negotiation. Example: '/rest-api/v1/users' (not '/rest-api/v1/users.json' or '/rest-api/v1/users.xml')
10. Use API Versioning Control for SEO and Scalability Implement API versioning in URLs to maintain backward compatibility as your API evolves. Include version numbers clearly in the URL for clarity and discoverability. Example: '/rest-api/v1/users', '/api/v2/users', 'rest-api.company.com/v1/users'
11. Be Consistent Across Endpoints for SEO and Usability Maintain consistent naming conventions, sorting, filtering, and pagination patterns across all API endpoints to create an intuitive, SEO-friendly structure that search engines and developers can easily navigate and index. Example: '/rest-api/v1/products?sort=name', '/rest-api/v1/products?sort=price', '/rest-api/v1/products?sort=desc'
12. Use Descriptive Parameter Names Ensure query parameters are descriptive and consistent across your API. Use common terms like status, type, id, category, and sort for clarity. Example: '/api/v1/products?category=electronics&sort=name', '/rest-api/v1/users?id=123'
13. Consider Resource Relationships for Hierarchies Use nested resources to represent relationships between entities, creating hierarchical, SEO-friendly URLs that are easy for search engines to crawl and developers to understand. Example: '/api/v1/users/123/orders', '/rest-api/v1/products/456/reviews'
14. Use HTTP Status Codes and Error Handling Use standard HTTP status codes to indicate API request outcomes, improving SEO and usability for developers/QAs searching for documentation: '200 OK' - Successful GET, PUT, or POST request '201 Created' - New resource successfully created '400 Bad Request' - Invalid request parameters, with clear error messages '404 Not Found' - Requested resource not found '500 Server Error' - Server-side issue, with detailed error responses for troubleshooting Provide clear, descriptive error messages in the response body (e.g., message, code, details) to enhance searchability and user experience for API documentation. { "status": 400, "message": "Invalid parameter value", "details": "User ID must be a positive integer", "code": "INVALID_PARAMETER" }
15. Secure Your REST API with Authentication Use Bearer tokens for API authentication (e.g., 'Authorization: Bearer '). Consider using standard authentication protocols like OAuth 2.0 for better security management. Example header: Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Security best practices:
- Always use HTTPS
- Implement rate limiting
- Set token expiration
- Validate all inputs
- Use secure headers