Repository Design Pattern in Django

Repository Design Pattern in Django

Table of contents

No heading

No headings in the article.

The Repository pattern can be implemented in Django by creating separate modules to handle database operations for each model, instead of spreading database queries throughout the application. Here are the basic steps to implement the Repository pattern:

  1. Create a separate repositories directory in your Django application.

  2. Create a base.py module in this directory that defines a base class for all repositories. This class should contain common methods that any repository can use.

from django.core.exceptions import ObjectDoesNotExist

class BaseRepository:
    model = None  # to be overridden by child classes

    @classmethod
    def get(cls, pk):
        try:
            return cls.model.objects.get(pk=pk)
        except ObjectDoesNotExist:
            return None

    @classmethod
    def create(cls, **kwargs):
        return cls.model.objects.create(**kwargs)

    @classmethod
    def update(cls, instance, **kwargs):
        for key, value in kwargs.items():
            setattr(instance, key, value)
        instance.save()
        return instance

    @classmethod
    def delete(cls, instance):
        instance.delete()

    @classmethod
    def all(cls):
        return cls.model.objects.all()
  1. Create a separate module for each model that needs a repository. For example, if you have a User model, you'd create a users.py module within the repositories directory.
from django.contrib.auth import get_user_model
from .base import BaseRepository

class UserRepository(BaseRepository):
    model = get_user_model()
  1. Use these repository classes in your views and other application code instead of calling model methods directly. For example, instead of calling User.objects.all(), you would call UserRepository.all().
from django.shortcuts import render
from .repositories.users import UserRepository

def list_users(request):
    users = UserRepository.all()
    return render(request, "users/list.html", {"users": users})

By using the Repository pattern, you can encapsulate database access in separate modules, make your code more modular, and decouple your application code from the details of the persistence layer.