Skip to content

zekavsrdev-code/LogiFood

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

48 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

LogiFood - Professional Django REST API

A professional logistics and product sales platform that enables Suppliers, Sellers, and Drivers to discover and work with each other.

System Overview

  • Supplier: Adds products to the system and offers them for sale
  • Seller: Places orders for products from suppliers
  • Driver: Delivers orders

πŸ—οΈ Project Structure

LogiFood/
β”œβ”€β”€ apps/                    # Core utilities and base classes
β”‚   └── core/               # Core app with base classes only
β”‚       β”œβ”€β”€ models.py       # Base models (TimeStampedModel)
β”‚       β”œβ”€β”€ serializers.py  # Base serializers
β”‚       β”œβ”€β”€ views.py        # Base viewsets
β”‚       β”œβ”€β”€ services.py     # Base service layer
β”‚       β”œβ”€β”€ utils.py        # Utility functions
β”‚       β”œβ”€β”€ exceptions.py   # Custom exceptions
β”‚       β”œβ”€β”€ permissions.py  # Custom permissions
β”‚       β”œβ”€β”€ pagination.py   # Custom pagination
β”‚       β”œβ”€β”€ filters.py      # Custom filters
β”‚       └── urls.py         # Core URLs (health check)
β”œβ”€β”€ apps/                    # Application modules (single root)
β”‚   β”œβ”€β”€ core/               # Shared base (models, utils, permissions, health)
β”‚   β”œβ”€β”€ users/               # User management module
β”‚   β”œβ”€β”€ products/           # Category, Product
β”‚   └── orders/             # Deal, Delivery, RequestToDriver, etc.
β”œβ”€β”€ tests/                   # Test suite (layered architecture)
β”‚   β”œβ”€β”€ conftest.py         # Shared pytest fixtures
β”‚   β”œβ”€β”€ test_users/         # User module tests
β”‚   β”‚   β”œβ”€β”€ test_models.py
β”‚   β”‚   β”œβ”€β”€ test_serializers.py
β”‚   β”‚   β”œβ”€β”€ test_services.py
β”‚   β”‚   └── test_views.py
β”‚   β”œβ”€β”€ test_products/      # Product module tests
β”‚   β”‚   β”œβ”€β”€ test_models.py
β”‚   β”‚   β”œβ”€β”€ test_serializers.py
β”‚   β”‚   β”œβ”€β”€ test_services.py
β”‚   β”‚   └── test_views.py
β”‚   β”œβ”€β”€ test_orders/        # Order module tests
β”‚   β”‚   β”œβ”€β”€ test_models.py
β”‚   β”‚   β”œβ”€β”€ test_serializers.py
β”‚   β”‚   β”œβ”€β”€ test_services.py
β”‚   β”‚   └── test_views.py
β”‚   └── test_core/          # Core utility tests
β”‚       β”œβ”€β”€ test_utils.py
β”‚       └── test_health_check.py
β”œβ”€β”€ config/                 # Project configuration
β”‚   β”œβ”€β”€ settings/           # Settings modules
β”‚   β”‚   β”œβ”€β”€ base.py        # Base settings
β”‚   β”‚   β”œβ”€β”€ development.py # Development settings
β”‚   β”‚   └── production.py  # Production settings
β”‚   β”œβ”€β”€ urls.py            # Main URL configuration
β”‚   β”œβ”€β”€ wsgi.py            # WSGI configuration
β”‚   └── asgi.py            # ASGI configuration
β”œβ”€β”€ static/                 # Static files
β”œβ”€β”€ media/                  # Media files
β”œβ”€β”€ templates/              # Template files
β”œβ”€β”€ logs/                   # Log files
β”œβ”€β”€ requirements.txt        # Python dependencies
β”œβ”€β”€ .env.example           # Environment variables template
β”œβ”€β”€ .gitignore             # Git ignore rules
β”œβ”€β”€ pytest.ini             # Pytest configuration
β”œβ”€β”€ manage.py              # Django management script
β”œβ”€β”€ setup_env.bat          # Windows setup script
└── setup_env.sh           # Linux/Mac setup script

πŸš€ Quick Start

Prerequisites

  • Python 3.10 or higher
  • PostgreSQL (recommended) or SQLite
  • pip

Quick Terminal Reference

Action Windows (CMD) Windows (Git Bash) Linux/Mac
Setup setup_env.bat bash setup_env.sh ./setup_env.sh
Activate venv venv\Scripts\activate.bat source venv/Scripts/activate source venv/bin/activate
Copy .env copy .env.example .env cp .env.example .env cp .env.example .env
Run server python manage.py runserver python manage.py runserver python manage.py runserver

Installation

Windows (Command Prompt)

  1. Run the setup script:
setup_env.bat
  1. Activate the virtual environment:
venv\Scripts\activate.bat

Windows (Git Bash) / Linux / Mac

  1. Make the setup script executable (Linux/Mac only):
chmod +x setup_env.sh
  1. Run the setup script:
# Windows (Git Bash)
bash setup_env.sh

# Linux/Mac
./setup_env.sh
  1. Activate the virtual environment:
# Windows (Git Bash)
source venv/Scripts/activate

# Linux/Mac
source venv/bin/activate

Configuration

  1. Copy the environment example file:
# Windows (Command Prompt)
copy .env.example .env

# Windows (Git Bash) / Linux / Mac
cp .env.example .env
  1. Edit .env file with your settings:

    • Set SECRET_KEY (generate a new one for production)
    • Configure database credentials
    • Set DEBUG=True for development
    • Configure other settings as needed
  2. Run migrations:

# Make sure virtual environment is activated first
python manage.py migrate
  1. Load initial data (market food categories):
python manage.py load_categories

This command loads market food categories including:

  • Main Categories: Citrus Fruits, Vegetables, Fruits, Legumes, Grains, Dairy Products, Meat and Meat Products, Fish and Seafood, Nuts and Dried Fruits, Spices and Herbs, Bakery Products, Beverages, Oils and Fats, Honey and Natural Products
  • Sub-categories: Leafy Vegetables, Root Vegetables, Nightshade Vegetables, Cucurbitaceae (under Vegetables); Stone Fruits, Berries, Tropical Fruits (under Fruits); Red Meat, Poultry, Processed Meat (under Meat); Milk and Cream, Cheese, Yogurt and Fermented Products (under Dairy)

To reset and reload all categories:

python manage.py load_categories --reset
  1. Create a superuser:
python manage.py createsuperuser
  1. Run the development server:
python manage.py runserver

Note: Always activate the virtual environment before running Django commands:

  • Windows (Command Prompt): venv\Scripts\activate.bat
  • Windows (Git Bash): source venv/Scripts/activate
  • Linux/Mac: source venv/bin/activate

The API will be available at http://localhost:8000/

🐳 Running with Docker

The project runs with Docker Compose (PostgreSQL, Redis, Django):

  1. Ensure Docker and Docker Compose are installed.

  2. Copy environment and set credentials (optional; defaults work with .env.example):

    cp .env.example .env
    # Edit .env: DB_PASSWORD, SECRET_KEY, etc.
  3. Start all services:

    docker compose up --build
  4. The API runs at http://localhost:8000/. Migrations run on startup.

  5. Dev data (categories + sample users/products/deals): set LOAD_DEV_DATA=1 in .env (or run once):

    docker compose exec web python manage.py load_dev_data

    With LOAD_DEV_DATA=1, the entrypoint runs load_dev_data after migrate so the stack starts with categories and sample data. Sample users’ password: sample123.

  6. Optional commands:

    docker compose up -d           # Run in background
    docker compose exec web python manage.py load_dev_data --reset  # Wipe and reload dev data
    docker compose exec web python manage.py createsuperuser
    docker compose exec web pytest -m unit
    docker compose down           # Stop and remove containers
    docker compose down -v        # Also remove volumes (DB data)

The web service uses DB_HOST=db and REDIS_URL=redis://redis:6379/1 via docker-compose.yml; your .env still provides DB_NAME, DB_USER, DB_PASSWORD, SECRET_KEY, etc.

πŸ“š API Documentation

Once the server is running, access the API documentation:

πŸ›οΈ Architecture & Design Decisions

Architectural Approach: Layered Architecture

This project follows a layered architecture pattern (also known as n-tier architecture), which separates concerns into distinct layers. This approach provides:

Architecture Layers

1. Models Layer (models.py)

Responsibility: Data structure and database representation

  • Django ORM: All database interactions use Django's Object-Relational Mapping
  • Base Models: TimeStampedModel provides automatic created_at, updated_at, and created_by fields
  • Custom User Model: Extended Django's AbstractUser with role-based system
  • Relationships: Foreign keys, OneToOne, and reverse relationships managed by ORM
  • Business Logic: Model methods for calculations and validations

Why Django ORM?

  • Type-safe queries with IDE autocomplete
  • Automatic SQL generation and optimization
  • Built-in migration system
  • Protection against SQL injection
  • Database abstraction (works with PostgreSQL, MySQL, SQLite)

2. Serializers Layer (serializers.py)

Responsibility: Data validation, transformation, and serialization

  • Input Validation: Validates incoming request data
  • Data Transformation: Converts between Python objects and JSON
  • Nested Serialization: Handles complex object relationships
  • Role-based Fields: Different fields based on user roles

3. Services Layer (services.py)

Responsibility: Business logic and orchestration

  • Business Rules: All business logic is centralized here
  • Transaction Management: Ensures data consistency with @transaction.atomic
  • Reusability: Service methods can be used by views, management commands, or other services
  • Testability: Business logic can be tested without HTTP layer
  • Error Handling: Custom BusinessLogicError for domain-specific errors

Why Service Layer?

  • Separation of Concerns: Views handle HTTP, services handle business logic
  • SOLID Principles: Single Responsibility (views = HTTP, services = business logic)
  • Reusability: Same business logic can be used in API, CLI, or background tasks
  • Testability: Business logic can be unit tested without HTTP overhead
  • Maintainability: Changes to business rules are centralized

4. Views Layer (views.py)

Responsibility: HTTP request/response handling

  • DRF Generic Views: Uses ViewSet and GenericAPIView for consistency
  • Permission Control: Role-based access control via custom permissions
  • Response Formatting: Standardized success/error responses
  • Minimal Logic: Views delegate to services, keeping them thin

Why DRF Generic Views?

  • Consistency: Standard patterns across all endpoints
  • Less Boilerplate: Built-in CRUD operations
  • Best Practices: Follows Django REST Framework conventions
  • API Documentation: Automatic schema generation for Swagger/ReDoc

5. Utils Layer (utils.py)

Responsibility: Helper functions and utilities

  • Response Helpers: Standardized API response formatting
  • Common Utilities: Reusable functions across the application

Design Patterns Used

  1. Repository Pattern: Service layer acts as repository, abstracting database operations
  2. Factory Pattern: Fixtures in tests create objects with default values
  3. Strategy Pattern: Different serializers based on action (create vs. update)
  4. Observer Pattern: Django signals for automatic profile creation

SOLID Principles Implementation

  • Single Responsibility: Each class has one reason to change

    • Models: Data structure
    • Serializers: Data validation/transformation
    • Services: Business logic
    • Views: HTTP handling
  • Open/Closed: Base classes (BaseService, TimeStampedModel) are open for extension, closed for modification

  • Liskov Substitution: All service classes can be used interchangeably through BaseService

  • Interface Segregation: Small, focused interfaces (permissions, serializers)

  • Dependency Inversion: Views depend on service abstractions, not concrete implementations

Database Structure

See the Database Structure section below for detailed information about models and relationships.

πŸ—„οΈ Database Structure

ORM Choice: Django ORM

This project uses Django ORM (Object-Relational Mapping) for all database operations. Django ORM provides:

  • Type Safety: IDE autocomplete and type checking
  • SQL Injection Protection: Parameterized queries by default
  • Database Abstraction: Works with PostgreSQL, MySQL, SQLite without code changes
  • Migration System: Version-controlled database schema changes
  • Query Optimization: select_related() and prefetch_related() for efficient queries
  • Relationship Management: Automatic handling of foreign keys, reverse relationships

Database Models and Relationships

Core Models

TimeStampedModel (Abstract Base Model)

  • created_at: Auto-populated timestamp
  • updated_at: Auto-updated timestamp
  • created_by: Foreign key to User (tracks who created the record)
  • All models inherit from this for consistent timestamp tracking

User Management Models

User (Custom User Model)

  • Extends Django's AbstractUser
  • Role System: SUPPLIER, SELLER, DRIVER
  • Relationships:
    • OneToOne β†’ SupplierProfile, SellerProfile, DriverProfile (via reverse relationships)

SupplierProfile

  • OneToOne with User
  • Relationships:
    • OneToMany β†’ Product (supplier.products)
    • OneToMany β†’ Deal (supplier.deals)

SellerProfile

  • OneToOne with User
  • Relationships:
    • OneToMany β†’ Deal (seller.deals)

DriverProfile

  • OneToOne with User
  • Relationships:
    • OneToMany β†’ Delivery (driver_profile.deliveries)
    • OneToMany β†’ RequestToDriver (driver.driver_requests)
    • Note: Driver information for deals is stored in RequestToDriver, not directly on Deal

Product Models

Category

  • Self-referential (parent-child hierarchy)
  • Relationships:
    • OneToMany β†’ Product (category.products)
    • Self β†’ Category (parent.children)

Product

  • Relationships:
    • ManyToOne β†’ SupplierProfile (product.supplier)
    • ManyToOne β†’ Category (product.category)
    • OneToMany β†’ DealItem (product.deal_items)
    • OneToMany β†’ DeliveryItem (product.delivery_items)

Order Models

Deal

  • Represents an agreement between Seller and Supplier
  • Relationships:
    • ManyToOne β†’ SellerProfile (deal.seller)
    • ManyToOne β†’ SupplierProfile (deal.supplier)
    • OneToMany β†’ DealItem (deal.items)
    • OneToMany β†’ Delivery (deal.deliveries)
    • OneToMany β†’ RequestToDriver (deal.driver_requests)

DealItem

  • Items within a Deal
  • Relationships:
    • ManyToOne β†’ Deal (item.deal)
    • ManyToOne β†’ Product (item.product)

Delivery

  • Actual delivery instance created from Deal
  • Relationships:
    • ManyToOne β†’ Deal (delivery.deal)
    • ManyToOne β†’ DriverProfile (delivery.driver_profile, nullable)
    • OneToMany β†’ DeliveryItem (delivery.items)

DeliveryItem

  • Items within a Delivery
  • Relationships:
    • ManyToOne β†’ Delivery (item.delivery)
    • ManyToOne β†’ Product (item.product)

RequestToDriver

  • Driver request/negotiation for a Deal
  • Relationships:
    • ManyToOne β†’ Deal (request.deal)
    • ManyToOne β†’ DriverProfile (request.driver)
    • Unique constraint: One request per driver per deal
  • Note: When a RequestToDriver is accepted (status=ACCEPTED), the driver information is used for creating deliveries. Driver information is no longer stored directly on Deal model.

Database Relationships Diagram

User (1) ──(1:1)── SupplierProfile (1) ──(1:N)── Product
                    β”‚
                    └──(1:N)── Deal ──(1:N)── Delivery
                                      β”‚
                                      └──(1:N)── RequestToDriver ──(N:1)── DriverProfile

User (1) ──(1:1)── SellerProfile (1) ──(1:N)── Deal

User (1) ──(1:1)── DriverProfile (1) ──(1:N)── Delivery
                    β”‚
                    └──(1:N)── RequestToDriver ──(N:1)── Deal

Category (self-referential)
    β”‚
    └──(1:N)── Product

Query Optimization

Django ORM provides several optimization techniques used in this project:

  1. select_related(): For ForeignKey and OneToOne relationships

    Deal.objects.select_related('seller', 'supplier')
    # Driver information is accessed via RequestToDriver: deal.driver_requests.filter(status='ACCEPTED').first()
  2. prefetch_related(): For ManyToMany and reverse ForeignKey relationships

    Category.objects.prefetch_related('children')
  3. only() / defer(): Load only needed fields

    Product.objects.only('name', 'price')

Migration Strategy

  • Version Control: All migrations are committed to git
  • Backward Compatibility: Migrations are designed to be reversible
  • Data Migrations: Custom migrations for data transformations (e.g., load_categories)
  • Zero Downtime: Migrations are designed to work with running applications

πŸ” Authentication

The project uses Django REST Framework Token Authentication. Email is optional; login is done with username.

Supplier Registration:

POST /api/auth/register/
{
    "username": "supplier1",
    "password": "securepassword123",
    "password2": "securepassword123",
    "role": "SUPPLIER",
    "company_name": "ABC Food Ltd.",
    "phone_number": "+15551234567",
    "city": "New York",
    "address": "123 Main St, New York"
}

Seller Registration:

POST /api/auth/register/
{
    "username": "seller1",
    "password": "securepassword123",
    "password2": "securepassword123",
    "role": "SELLER",
    "business_name": "Central Market",
    "business_type": "Market",
    "phone_number": "+15559876543",
    "city": "Boston",
    "address": "456 Oak Ave, Boston"
}

Driver Registration:

POST /api/auth/register/
{
    "username": "driver1",
    "password": "securepassword123",
    "password2": "securepassword123",
    "role": "DRIVER",
    "license_number": "34ABC123",
    "vehicle_type": "VAN",
    "vehicle_plate": "34 ABC 123",
    "phone_number": "+15557654321",
    "city": "New York"
}

Login (with username):

POST /api/auth/login/
{
    "username": "supplier1",
    "password": "securepassword123"
}

Accessing protected endpoints:

Include the JWT token in the Authorization header:

Authorization: Bearer <access_token>

πŸ“¦ API Endpoints

Auth Endpoints

Method URL Description
POST /api/auth/register/ User registration (role-based)
POST /api/auth/login/ Login (with username)
POST /api/auth/logout/ Logout
GET/PUT /api/auth/profile/ View/update profile
GET/PUT /api/auth/profile/role/ View/update role profile
POST /api/auth/change-password/ Change password
PUT /api/auth/toggle-availability/ Driver availability toggle

Product Endpoints

Method URL Description
GET /api/products/categories/ List categories
GET /api/products/items/ List all products
GET /api/products/items/<id>/ Product detail
GET/POST /api/products/my-products/ Supplier products (own)
GET/PUT/DELETE /api/products/my-products/<id>/ Supplier product management

Order Endpoints

Method URL Description
GET/POST /api/orders/deals/ Deal list/create
GET/PUT/DELETE /api/orders/deals/<id>/ Deal detail/update/delete
POST /api/orders/deals/<id>/approve/ Approve deal
PUT /api/orders/deals/<id>/update_status/ Update deal status
PUT /api/orders/deals/<id>/assign_driver/ Assign driver to deal (creates and auto-approves RequestToDriver)
PUT /api/orders/deals/<id>/request_driver/ Request driver for deal (creates RequestToDriver)
POST /api/orders/deals/<id>/complete/ Complete deal and create deliveries
GET/POST /api/orders/driver-requests/ Driver request list/create
GET/PUT /api/orders/driver-requests/<id>/ Driver request detail/update
POST /api/orders/driver-requests/<id>/approve/ Approve driver request
GET /api/orders/deliveries/ Delivery list
GET /api/orders/deliveries/<id>/ Delivery detail
PUT /api/orders/deliveries/<id>/update_status/ Update delivery status
PUT /api/orders/deliveries/<id>/assign_driver/ Assign driver to delivery (supplier only)

Discovery Endpoints

Method URL Description
GET /api/users/profiles/ List profiles by role (SUPPLIER, SELLER, DRIVER)
GET /api/orders/available-deliveries/ Available deliveries for drivers
POST /api/orders/accept-delivery/<id>/ Driver accept delivery

πŸ§ͺ Testing Strategy

This project follows a comprehensive testing strategy with 77% code coverage (src + apps), ensuring reliability and maintainability.

Testing Philosophy

We use pytest as our primary testing framework, following the AAA pattern (Arrange-Act-Assert) for clear and readable tests. Our testing strategy covers three main levels:

1. Unit Tests

Test individual components in isolation:

  • Models (test_models.py): Test model methods, validations, relationships, and business logic
  • Serializers (test_serializers.py): Test data validation, transformation, and serialization logic
  • Services (test_services.py): Test business logic, data operations, and service layer methods

Example Unit Test:

def test_create_deal(self, seller_user, supplier_user):
    """Test creating a deal"""
    deal = Deal.objects.create(
        seller=seller_user.seller_profile,
        supplier=supplier_user.supplier_profile,
        delivery_handler=Deal.DeliveryHandler.SYSTEM_DRIVER,
        status=Deal.Status.DEALING
    )
    assert deal.seller == seller_user.seller_profile
    assert deal.status == Deal.Status.DEALING

2. Integration Tests

Test component interactions and API endpoints:

  • Views (test_views.py): Test API endpoints, authentication, permissions, and request/response handling
  • End-to-End Flows: Test complete user workflows (registration β†’ product creation β†’ deal β†’ delivery)

Example Integration Test:

def test_create_deal_as_seller(self, seller_client, supplier_user, product):
    """Test seller can create a deal"""
    response = seller_client.post('/api/orders/deals/', {
        'supplier_id': supplier_user.supplier_profile.id,
        'items': [{'product_id': product.id, 'quantity': 10}]
    })
    assert response.status_code == 201
    assert Deal.objects.count() == 1

3. Test Fixtures and Organization

Shared Fixtures (tests/conftest.py):

  • api_client: DRF API client for making requests
  • user, supplier_user, seller_user, driver_user: User fixtures with different roles
  • product, category, deal: Domain object fixtures
  • authenticated_client, supplier_client, etc.: Pre-authenticated API clients

Test Organization:

The test suite follows a layered architecture pattern, mirroring the application structure:

tests/
β”œβ”€β”€ conftest.py                    # Shared pytest fixtures
β”œβ”€β”€ test_users/                   # User module tests
β”‚   β”œβ”€β”€ test_models.py           # User model unit tests
β”‚   β”œβ”€β”€ test_serializers.py      # User serializer tests
β”‚   β”œβ”€β”€ test_services.py         # User service layer tests
β”‚   └── test_views.py            # User API integration tests
β”œβ”€β”€ test_products/               # Product module tests
β”‚   β”œβ”€β”€ test_models.py           # Product/Category model tests
β”‚   β”œβ”€β”€ test_serializers.py      # Product serializer tests
β”‚   β”œβ”€β”€ test_services.py         # Product service layer tests
β”‚   └── test_views.py            # Product API integration tests
β”œβ”€β”€ test_orders/                 # Order module tests
β”‚   β”œβ”€β”€ test_models.py           # Deal/Delivery/RequestToDriver model tests
β”‚   β”œβ”€β”€ test_serializers.py      # Order serializer tests
β”‚   β”œβ”€β”€ test_services.py        # Order service layer tests
β”‚   └── test_views.py            # Order API integration tests
β”œβ”€β”€ test_e2e/                    # End-to-end flow tests (API-only)
β”‚   └── test_order_flow.py       # Full order flows via HTTP
└── test_core/                   # Core utility tests
    β”œβ”€β”€ test_utils.py
    └── test_health_check.py

Test Organization Principles:

  • One file per layer: Each module has separate test files for models, serializers, services, and views
  • Consistent structure: All modules follow the same test organization pattern
  • Clear separation: Unit tests (models, serializers, services) are separate from integration tests (views)
  • E2E layer: Full user journeys are tested in test_e2e/ via API only (no direct DB manipulation)
  • Markers: Unit tests use pytest.mark.unit, integration tests (views, health check) use pytest.mark.integration, E2E tests use pytest.mark.e2e β€” run with pytest -m unit, pytest -m integration, pytest -m e2e
  • Shared fixtures: Common test data is defined in conftest.py for reusability

This organization ensures:

  • Maintainability: Easy to find and update tests for specific layers
  • Scalability: New modules can follow the same pattern
  • Clarity: Test structure mirrors application architecture
  • Best Practices: Follows industry-standard testing patterns

Running Tests

Run all tests:

pytest

Run with coverage report:

pytest --cov --cov-report=term-missing

Run specific test file:

pytest tests/test_users/test_views.py

Run specific test:

pytest tests/test_users/test_views.py::TestUserLogin::test_login_success

Run tests by marker:

pytest -m unit          # Run only unit tests
pytest -m integration  # Run only integration tests
pytest -m e2e           # Run only end-to-end flow tests
pytest -m "not slow"    # Skip slow tests

Test Coverage

Current test coverage: 88% (run pytest --cov=apps --cov-report=term-missing)

Coverage is maintained through:

  • Comprehensive unit tests for all models and services
  • Integration tests for all API endpoints
  • Edge case testing for business logic
  • Error handling and validation testing

πŸ“¦ Key Features

  • βœ… Professional project structure with apps/ for modules (single root)
  • βœ… Environment-based configuration
  • βœ… Layered architecture (Models, Views, Serializers, Services)
  • βœ… Token Authentication (Django REST Framework)
  • βœ… Custom User Model
  • βœ… API Documentation (Swagger/ReDoc)
  • βœ… CORS support
  • βœ… Database abstraction (PostgreSQL ready)
  • βœ… Logging configuration
  • βœ… Development/Production settings separation
  • βœ… Base classes for reusability
  • βœ… Custom exceptions and permissions
  • βœ… Pagination support
  • βœ… Comprehensive test suite with pytest

πŸ› οΈ Development Tools

All commands below require the virtual environment to be activated.

Management Commands

  • Load Categories: Load market food categories into the database
    python manage.py load_categories
    To reset and reload all categories:
    python manage.py load_categories --reset

Code Quality Tools

  • Django Debug Toolbar: Available in development mode
  • Black: Code formatting
    black .
  • isort: Import sorting
    isort .
  • flake8: Linting
    flake8 .
  • pytest: Testing framework (see Testing section above)

πŸ“ Adding New Modules

  1. Create a new module in apps/:
mkdir -p apps/<module_name>
  1. Create the module structure:

    • __init__.py
    • apps.py - Django app config (set name = 'apps.<module_name>' and label = '<module_name>')
    • models.py - Database models
    • serializers.py - Data serialization
    • views.py - API views
    • urls.py - URL routing
    • services.py - Business logic
    • admin.py - Admin configuration
    • utils.py - Module utilities (optional)
  2. Add the module to INSTALLED_APPS in config/settings/base.py:

LOCAL_APPS = [
    'apps.core',
    'apps.users',
    'apps.products',
    'apps.orders',
    'apps.<module_name>',  # Add your new module
]
  1. Include URLs in config/urls.py:
path('api/<module_path>/', include('apps.<module_name>.urls')),
  1. Create tests in tests/test_<module_name>/:
    • test_models.py
    • test_views.py
    • test_serializers.py
    • test_services.py

πŸ”’ Security Notes

  • Never commit .env file to version control
  • Use strong SECRET_KEY in production
  • Set DEBUG=False in production
  • Configure ALLOWED_HOSTS properly
  • Use HTTPS in production
  • Keep dependencies updated

πŸ“„ License

This project is open source and available under the MIT License.

🀝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages