Django Service Layer - DjangoCon EU 2018

Where do we put business logic in Django?

In a model

class User(models.Model):
    ...
    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)

        create_profile(user=self)
        send_user_email(user=self)

In a plain view

class CreateUserView(View):
    ...
    def post(self, *args, **kwargs):
        user = User.objects.create(...)

        create_profile(user=user)
        send_user_email(user=user)

        return SomeHttpResponse(...)

In an API

class CreateUserApi(APIView):
    ...
    def post(self, *args, **kwargs):
        user = User.objects.create(...)

        create_profile(user=user)
        send_user_email(user=user)

        return SomeHttpResponse(...)

Also - ModelForm, CreateAPIView, ModelViewSet

A note on abstraction

If you are putting something in your database, use as little abstraction as possible

If you are getting our something from your database, use as much abstraction as needed.

services.py

def create_user(
    *,
    email: str,
    name: str
) -> User:
    user = User(email=email)
    user.full_clean()
    user.save()

    create_profile(user=user, name=name)
    send_user_email(user=user)

    return user
class CreateUserApi(APIView):
    class InputSerializer(Serializer):
        email = serializers.EmailField()
        name = serializers.CharField()

    def post(self, data, *args, **kwargs):
        serializer = self.InputSerializer(
            data=request.data
        )
        serializer.is_valid(
            raise_exception=True
        )

        data = serializer.validated_data

        user = create_user(
            email=data['email'],
            name=data['name']
        )

        return SomeHttpResponse(...)

Django Service Layer - DjangoCon EU 2018

By Hack Bulgaria

Django Service Layer - DjangoCon EU 2018

  • 2,004