{ "info": { "author": "Mitchel Cabuloy", "author_email": "mixxorz@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Plugins", "Environment :: Web Environment", "Framework :: Django", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Topic :: Internet :: WWW/HTTP", "Topic :: Internet :: WWW/HTTP :: Dynamic Content" ], "description": "# django-service-objects [![Latest Version][latest-version-image]][latest-version-link]\n[![Build Status][build-status-image]][build-status-link] [![Python Support][python-support-image]][python-support-link] [![License][license-image]][license-link]\n\nService objects for Django\n\n## What?\n\nThis 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](http://mitchel.me/2017/django-service-objects/), 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.\n\n## Installation guide\n\nInstall from pypi:\n\n`pip install django-service-objects`\n\nAdd `service_objects` to your `INSTALLED_APPS`:\n\n```python\n# settings.py\n\nINSTALLED_APPS = (\n ...\n 'service_objects',\n ...\n)\n```\n\n## Example\n\nLet's say you want to register new users. You could make a `CreateUser` service.\n\n```python\nfrom service_objects.services import Service\n\nclass CreateUser(Service):\n email = forms.EmailField()\n password = forms.CharField(max_length=255)\n subscribe_to_newsletter = forms.BooleanField(required=False)\n\n def process(self):\n email = self.cleaned_data['email']\n password = self.cleaned_data['password']\n subscribe_to_newsletter = self.cleaned_data['subscribe_to_newsletter']\n\n user = User.objects.create_user(\n username=email, email=email, password=password)\n\n if subscribe_to_newsletter:\n newsletter = Newsletter.objects.get()\n newsletter.subscribers.add(user)\n newsletter.save()\n \n WelcomeEmail.send(user, is_subscribed=subsribe_to_newsletter)\n\n return user\n```\n\nNotice 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`.\n\nHere's how you use it:\n\n```python\nCreateUser.execute({\n 'email': 'kvothe@edemaruh.com',\n 'password': 'doorsofstone',\n 'subscribe_to_newsletter': True,\n})\n```\n\nNow you can use it anywhere.\n\nIn your views\n\n```python\n# views.py\n\n# Function Based View\ndef create_user_view(request):\n form = NewUserForm()\n if request.method == 'POST':\n form = NewUserForm(request.POST)\n\n if form.is_valid():\n try:\n CreateUser.execute(request.POST)\n return redirect('/success/')\n except Exception:\n form.add_error(None, 'Something went wrong')\n\n return render(request, 'registration/new-user.html', {'form': form})\n\n\n# Class Based View\nclass CreateUserView(ServiceView):\n form_class = NewUserForm\n service_class = CreateUser\n template_name = 'registration/new-user.html'\n success_url = '/success/'\n\n```\n\nA management command\n\n```python\n# management/commands/create_user.py\n\nclass Command(BaseCommand):\n help = \"Creates a new user\"\n\n def add_arguments(self, parser):\n parser.add_argument('email')\n parser.add_argument('password')\n\n def handle(self, *args, **options):\n user = CreateUser.execute(options)\n self.stdout.write(f'New user created : {user.email}')\n\n```\n\nIn your tests\n\n```python\nclass CreateUserTest(TestCase):\n\n def test_create_user(self):\n inputs = {\n 'email': 'kvothe@edemaruh.com',\n 'password': 'do0r$0f$stone42',\n 'subscribe_to_newsletter': True,\n }\n\n CreateUser.execute(inputs)\n\n user = User.objects.get()\n self.assertEqual(user.email, inputs['email'])\n\n newsletter = Newsletter.objects.get()\n self.assertIn(user, newsletter.subscribers.all())\n```\n\nAnd anywhere you want. You can even execute services inside other services. The possibilities are endless!\n\n## Documentation\n\nDocs can be found on [readthedocs](http://django-service-objects.readthedocs.io/en/stable/).\n\nIf you have any questions about service objects, you can tweet me [@mixxorz](https://twitter.com/mixxorz).\n\n[latest-version-image]: https://img.shields.io/pypi/v/django-service-objects.svg\n[latest-version-link]: https://pypi.org/project/django-service-objects/\n[build-status-image]: https://img.shields.io/travis/mixxorz/django-service-objects/master.svg\n[build-status-link]: https://travis-ci.org/mixxorz/django-service-objects\n[python-support-image]: https://img.shields.io/pypi/pyversions/django-service-objects.svg\n[python-support-link]: https://pypi.org/project/django-service-objects/\n[license-image]: https://img.shields.io/pypi/l/django-service-objects.svg\n[license-link]: https://github.com/mixxorz/django-service-objects/blob/master/LICENSE", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/mixxorz/django-service-objects", "keywords": "", "license": "MIT License", "maintainer": "Mitchel Cabuloy", "maintainer_email": "mixxorz@gmail.com", "name": "django-service-objects", "package_url": "https://pypi.org/project/django-service-objects/", "platform": "", "project_url": "https://pypi.org/project/django-service-objects/", "project_urls": { "Homepage": "https://github.com/mixxorz/django-service-objects" }, "release_url": "https://pypi.org/project/django-service-objects/0.5.0/", "requires_dist": null, "requires_python": "", "summary": "Service objects for Django", "version": "0.5.0" }, "last_serial": 4209987, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "9e105b72883fd4f15aef13473151792b", "sha256": "df730b7e4c8eee6ee7d7ff14a01110807ca5bc79da34be8cca2fb7576623e74a" }, "downloads": -1, "filename": "django-service-objects-0.1.0.tar.gz", "has_sig": false, "md5_digest": "9e105b72883fd4f15aef13473151792b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2230, "upload_time": "2017-08-13T16:33:05", "url": "https://files.pythonhosted.org/packages/ae/55/4aba42e301b5003b5cb43dac782917b49080619b1847166ba0e2d70d32b6/django-service-objects-0.1.0.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "4a3866b984fd1cfa1fb7065653b66f61", "sha256": "6684bb448d02d536737171f8bb8c4f1d066d0ec051f82b8f92c16f932b956e30" }, "downloads": -1, "filename": "django-service-objects-0.2.0.tar.gz", "has_sig": false, "md5_digest": "4a3866b984fd1cfa1fb7065653b66f61", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3730, "upload_time": "2017-09-02T05:38:12", "url": "https://files.pythonhosted.org/packages/60/b7/91c5081fe528857ab8b728e53b6ec143190715bcf7d4b4672f7a6d1303f8/django-service-objects-0.2.0.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "dc9aa6ae7380b47704bead5376c56471", "sha256": "296a89fab23592eb7db0a4494df05333407faa767934df8ca0e62d8944e5e855" }, "downloads": -1, "filename": "django-service-objects-0.3.0.tar.gz", "has_sig": false, "md5_digest": "dc9aa6ae7380b47704bead5376c56471", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3816, "upload_time": "2017-12-14T08:08:32", "url": "https://files.pythonhosted.org/packages/9b/26/9edd99d1be9e0b0e3c91b2714f383ece39283f93e0ba6218793143d5a871/django-service-objects-0.3.0.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "0c21135ae77854efdefe9c315c3451ef", "sha256": "73d73cb586a8113ba43fe092438892e31abd8e647800b5770dab99abddfd38da" }, "downloads": -1, "filename": "django-service-objects-0.3.1.tar.gz", "has_sig": false, "md5_digest": "0c21135ae77854efdefe9c315c3451ef", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3819, "upload_time": "2017-12-30T03:33:42", "url": "https://files.pythonhosted.org/packages/fa/24/1e3ba468eb916393edc7b3cf278c052e662f29e415cb869c69c2b7924d60/django-service-objects-0.3.1.tar.gz" } ], "0.4.0": [ { "comment_text": "", "digests": { "md5": "2edcfa03e43e27d3de9dc2cc85e05c94", "sha256": "4970c5aee725566f91aae95dd78da151a242edaae3e0c332a51688de059d5763" }, "downloads": -1, "filename": "django-service-objects-0.4.0.tar.gz", "has_sig": false, "md5_digest": "2edcfa03e43e27d3de9dc2cc85e05c94", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6562, "upload_time": "2018-03-30T12:30:55", "url": "https://files.pythonhosted.org/packages/1e/36/205b648b6b00ef5e3d860f2a59910f5355ce7ea93200e379d374892ff3dd/django-service-objects-0.4.0.tar.gz" } ], "0.5.0": [ { "comment_text": "", "digests": { "md5": "e8ceb0c69728372d2bfa71dd09ca4029", "sha256": "15b8bcf1cdb90d3d3f9873721792410da4e31504a90de99fca4e6ad8c14dcae9" }, "downloads": -1, "filename": "django-service-objects-0.5.0.tar.gz", "has_sig": false, "md5_digest": "e8ceb0c69728372d2bfa71dd09ca4029", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8354, "upload_time": "2018-08-27T06:32:29", "url": "https://files.pythonhosted.org/packages/b9/80/3028c1064ee50591949f21a690476b8b86517c2d209420329024a9e5abbd/django-service-objects-0.5.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "e8ceb0c69728372d2bfa71dd09ca4029", "sha256": "15b8bcf1cdb90d3d3f9873721792410da4e31504a90de99fca4e6ad8c14dcae9" }, "downloads": -1, "filename": "django-service-objects-0.5.0.tar.gz", "has_sig": false, "md5_digest": "e8ceb0c69728372d2bfa71dd09ca4029", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8354, "upload_time": "2018-08-27T06:32:29", "url": "https://files.pythonhosted.org/packages/b9/80/3028c1064ee50591949f21a690476b8b86517c2d209420329024a9e5abbd/django-service-objects-0.5.0.tar.gz" } ] }