Crea apps Django con arquitectura DDD
Project description
🧠 Arquitectura Basada en DDD para Django Rest Framework
🚀 Instalación
Puedes instalarlo directamente desde PyPI:
pip install django-ddd-template
🚀 Después de instalar el paquete, puedes usar el siguiente comando para generar una app con estructura DDD:
django-ddd startapp <nombre_de_la_app>
📦 Estructura General
Esta estructura está basada en los principios de Domain-Driven Design (DDD) aplicada con Django + Django Rest Framework.
entity_app/
├── domain/
│ ├── entities/ # Entidades del dominio
│ ├── events/ # Eventos de dominio
│ ├── repositories/ # Interfaces de repositorios
│ └── services/ # Lógica de negocio
├── infrastructure/
│ ├── models/ # Modelos ORM
│ ├── repositories/ # Repositorios concretos
│ ├── serializers/ # Serializadores DRF
│ ├── views/ # Vistas DRF
│ └── urls.py # Enrutamiento de la app
├── migrations/ # Migraciones Django
├── apps.py # Configuración de la app
├── models.py # Opcional si se usa infraestructura/models
└── tests/ # Pruebas unitarias
🧱 Ejemplo de Implementación
Dominio
Entidad
# domain/entities/entity.py
class Entity:
def __init__(self, id, name, value):
self.id = id
self.name = name
self.value = value
Repositorio (interfaz)
# domain/repositories/entity_repository.py
from abc import ABC, abstractmethod
class EntityRepository(ABC):
@abstractmethod
def get_by_id(self, entity_id): pass
@abstractmethod
def save(self, entity): pass
Servicio
# domain/services/entity_service.py
from entity_app.domain.entities.entity import Entity
class EntityService:
def __init__(self, repository):
self.repository = repository
def register_entity(self, name, value):
entity = Entity(None, name, value)
return self.repository.save(entity)
Infraestructura
Modelo
# infrastructure/models/entity_model.py
from django.db import models
class EntityModel(models.Model):
name = models.CharField(max_length=255)
value = models.IntegerField()
Repositorio (implementación)
# infrastructure/repositories/django_entity_repository.py
from entity_app.domain.entities.entity import Entity
from entity_app.domain.repositories.entity_repository import EntityRepository
from entity_app.infrastructure.models.entity_model import EntityModel
class DjangoEntityRepository(EntityRepository):
def get_by_id(self, entity_id):
model = EntityModel.objects.get(id=entity_id)
return Entity(model.id, model.name, model.value)
def save(self, entity):
model = EntityModel(name=entity.name, value=entity.value)
model.save()
entity.id = model.id
return entity
Serializador
# infrastructure/serializers/entity_serializer.py
from rest_framework import serializers
from entity_app.infrastructure.models.entity_model import EntityModel
class EntitySerializer(serializers.ModelSerializer):
class Meta:
model = EntityModel
fields = ['id', 'name', 'value']
Vista
# infrastructure/views/entity_view.py
from rest_framework import viewsets
from entity_app.infrastructure.models.entity_model import EntityModel
from entity_app.infrastructure.serializers.entity_serializer import EntitySerializer
class EntityViewSet(viewsets.ModelViewSet):
queryset = EntityModel.objects.all()
serializer_class = EntitySerializer
URLs
# infrastructure/urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from entity_app.infrastructure.views.entity_view import EntityViewSet
router = DefaultRouter()
router.register(r'entities', EntityViewSet)
urlpatterns = [
path('', include(router.urls)),
]
✅ Pruebas
# tests/test_entity_service.py
import unittest
from entity_app.domain.services.entity_service import EntityService
from entity_app.domain.entities.entity import Entity
class InMemoryEntityRepository:
def __init__(self):
self.data = {}
self._id_counter = 1
def get_by_id(self, entity_id):
return self.data.get(entity_id)
def save(self, entity):
entity.id = self._id_counter
self.data[self._id_counter] = entity
self._id_counter += 1
return entity
class EntityServiceTestCase(unittest.TestCase):
def test_register_entity(self):
repo = InMemoryEntityRepository()
service = EntityService(repo)
entity = service.register_entity("Example", 100)
self.assertIsNotNone(entity.id)
self.assertEqual(entity.name, "Example")
self.assertEqual(entity.value, 100)
if __name__ == '__main__':
unittest.main()
▶️ Ejecución de Pruebas
python manage.py test entity_app.tests.test_entity_service
📌 Notas
- Se recomienda inyectar las dependencias (repositorios) desde vistas o gestores.
- Puedes extender
servicescon lógica más compleja según tus reglas de negocio.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file django_ddd_template-0.5.tar.gz.
File metadata
- Download URL: django_ddd_template-0.5.tar.gz
- Upload date:
- Size: 6.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.9.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c67a613e3f9441efd0907f726b250912be72dee71d6f1c9297d91f5a6a82bf02
|
|
| MD5 |
d1eca803762634f02324b3d32544cb0a
|
|
| BLAKE2b-256 |
01cb166531f50a2ee8ce5deda3ca2b4da835ed966ead513af22483081b59e8f0
|
File details
Details for the file django_ddd_template-0.5-py3-none-any.whl.
File metadata
- Download URL: django_ddd_template-0.5-py3-none-any.whl
- Upload date:
- Size: 6.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.9.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1673864327e25c0adaf7b7c2e98d07811124d9f7cf7accc420d37dd51a5b63ed
|
|
| MD5 |
be108f654da6ae4e7e08ae9055e80f59
|
|
| BLAKE2b-256 |
45fe6aa9c3b002339ff5e9baad7c4ea8df93e5c5b1bf15e17d5c2c1951d1b1e1
|