All Projects → mixxorz → Django Service Objects

mixxorz / Django Service Objects

Licence: mit
Service objects for Django

Programming Languages

python
139335 projects - #7 most used programming language

Projects that are alternatives of or similar to Django Service Objects

Urf.core.sample
URF.Core Sample Solution - E2E sample built with ASP.NET Core, Entity Framework Core, URF.Core, Angular, Kendo UI & OData Core. Live demo: https://goo.gl/QpJVgd
Stars: ✭ 40 (-86.16%)
Mutual labels:  service, design-patterns
Django Datatable View
Server-side datatable representations for Django querysets for automatic rendering in templates
Stars: ✭ 282 (-2.42%)
Mutual labels:  django
Quicklib
Quick development library (AutoMapper, LinQ, IOC Dependency Injection, MemoryCache, Scheduled tasks, Config, Serializers, etc) with crossplatform support for Delphi/Firemonkey (Windows,Linux,OSX/IOS/Android) and freepascal (Windows/Linux).
Stars: ✭ 274 (-5.19%)
Mutual labels:  service
Django Schema Graph
An interactive graph of your Django model structure
Stars: ✭ 278 (-3.81%)
Mutual labels:  django
Wagtailmenus
An app to help you manage and render menus in your Wagtail projects more effectively
Stars: ✭ 275 (-4.84%)
Mutual labels:  django
Django Querycount
Middleware that Prints the number of DB queries to the runserver console.
Stars: ✭ 280 (-3.11%)
Mutual labels:  django
Unity Programming Patterns
A collection of programming patterns in Unity with examples when to use them. These are primarily from the book "Game Programming Patterns," but translated from C++ to C#
Stars: ✭ 272 (-5.88%)
Mutual labels:  design-patterns
Python Articles
Monthly Series - Top 10 Python Articles
Stars: ✭ 288 (-0.35%)
Mutual labels:  django
Game Programming Patterns
Source repo for the book
Stars: ✭ 3,096 (+971.28%)
Mutual labels:  design-patterns
Try Django 19
Try Django 1.9 is an introduction to Django version 1.9 by creating a simple, yet robust, Django blog. This series covers a variety of Django basics as well as Django 1.9 specific material. Created by Team CFE @ http://joincfe.com.
Stars: ✭ 279 (-3.46%)
Mutual labels:  django
Longclaw
A shop for Wagtail CMS
Stars: ✭ 278 (-3.81%)
Mutual labels:  django
Djangoforprofessionals
Source code for Django for Professionals
Stars: ✭ 274 (-5.19%)
Mutual labels:  django
Socialhome
A federated social home
Stars: ✭ 282 (-2.42%)
Mutual labels:  django
Openciviwiki
Building a Better Democracy for the Internet Age
Stars: ✭ 275 (-4.84%)
Mutual labels:  django
Django Honeypot
🍯 Generic honeypot utilities for use in django projects.
Stars: ✭ 284 (-1.73%)
Mutual labels:  django
Admin Dashboards
Admin Dashboards - Open-Source and Free | AppSeed
Stars: ✭ 275 (-4.84%)
Mutual labels:  django
Django Page Cms
Official Django page CMS git repository
Stars: ✭ 277 (-4.15%)
Mutual labels:  django
Chatire
💬 Real time Chat application built with Vue, Django, RabbitMQ and uWSGI WebSockets.
Stars: ✭ 278 (-3.81%)
Mutual labels:  django
Mozillians
Mozilla community directory -- A centralized directory of all Mozilla contributors!
Stars: ✭ 288 (-0.35%)
Mutual labels:  django
Zqxt
自强学堂源代码 https://code.ziqiangxuetang.com/django/django-tutorial.html
Stars: ✭ 287 (-0.69%)
Mutual labels:  django

django-service-objects Latest Version

Build Status Python Support PyPI - Django Version License

Service objects for Django

What?

This is a small library providing a Service base class to derive your service objects from. What are service objects? You can read more about the whys and hows in this blog post, but for the most part, it encapsulates your business logic, decoupling it from your views and model methods. Put your business logic in service objects.

Installation guide

Install from pypi:

pip install django-service-objects

Add service_objects to your INSTALLED_APPS:

# settings.py

INSTALLED_APPS = (
    ...
    'service_objects',
    ...
)

Example

Let's say you want to register new users. You could make a CreateUser service.

from django import forms

from service_objects.services import Service

class CreateUser(Service):
    email = forms.EmailField()
    password = forms.CharField(max_length=255)
    subscribe_to_newsletter = forms.BooleanField(required=False)

    def process(self):
        email = self.cleaned_data['email']
        password = self.cleaned_data['password']
        subscribe_to_newsletter = self.cleaned_data['subscribe_to_newsletter']

        self.user = User.objects.create_user(username=email, email=email, password=password)
        self.subscribe_to_newsletter = subscribe_to_newsletter

        if self.subscribe_to_newsletter:
            newsletter = Newsletter.objects.get()
            newsletter.subscribers.add(self.user)
            newsletter.save()
            
        return self.user
    
    def post_process(self):
        WelcomeEmail.send(self.user, is_subscribed=self.subsribe_to_newsletter)
        
        # Calling a celery task after successfully creating the user.
        create_billing_account.delay(self.user.id)

Notice that it's basically a Django form but with a process method. This method gets called when you call execute() on the process. If your inputs are invalid, it raises InvalidInputsError.

The newly added post_process can also be included for running extra tasks that need to be executed after the service completes.

Here's how you use it:

CreateUser.execute({
    'email': '[email protected]',
    'password': 'doorsofstone',
    'subscribe_to_newsletter': True,
})

Now you can use it anywhere.

In your views

# views.py

# Function Based View
def create_user_view(request):
    form = NewUserForm()
    if request.method == 'POST':
        form = NewUserForm(request.POST)

        if form.is_valid():
            try:
                CreateUser.execute(request.POST)
                return redirect('/success/')
            except Exception:
                form.add_error(None, 'Something went wrong')

    return render(request, 'registration/new-user.html', {'form': form})


# Class Based View
class CreateUserView(ServiceView):
    form_class = NewUserForm
    service_class = CreateUser
    template_name = 'registration/new-user.html'
    success_url = '/success/'

A management command

# management/commands/create_user.py

class Command(BaseCommand):
    help = "Creates a new user"

    def add_arguments(self, parser):
        parser.add_argument('email')
        parser.add_argument('password')

    def handle(self, *args, **options):
        user = CreateUser.execute(options)
        self.stdout.write(f'New user created : {user.email}')

In your tests

class CreateUserTest(TestCase):

    def test_create_user(self):
        inputs = {
            'email': '[email protected]',
            'password': 'do0r$0f$stone42',
            'subscribe_to_newsletter': True,
        }

        CreateUser.execute(inputs)

        user = User.objects.get()
        self.assertEqual(user.email, inputs['email'])

        newsletter = Newsletter.objects.get()
        self.assertIn(user, newsletter.subscribers.all())

And anywhere you want. You can even execute services inside other services. The possibilities are endless!

Documentation

Docs can be found on readthedocs.

If you have any questions about service objects, you can tweet me @mixxorz.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].