# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['easy_tenants']

package_data = \
{'': ['*']}

install_requires = \
['django-appconf>=1.0.4,<2.0.0', 'django>=3.0.4,<4.0.0']

setup_kwargs = {
    'name': 'django-easy-tenants',
    'version': '0.2.0',
    'description': 'Easy to create applications that use tenants in django',
    'long_description': '# easy-tenants\n\n![Tests](https://github.com/CleitonDeLima/django-easy-tenants/workflows/Tests/badge.svg)\n[![Coverage Status](https://coveralls.io/repos/github/CleitonDeLima/django-easy-tenants/badge.svg?branch=github-ci)](https://coveralls.io/github/CleitonDeLima/django-easy-tenants?branch=github-ci)\n[![PyPI Version](https://img.shields.io/pypi/v/django-easy-tenants.svg)](https://pypi.org/project/django-easy-tenants/)\n[![PyPI downloads](https://img.shields.io/pypi/dm/django-easy-tenants.svg)](https://img.shields.io/pypi/dm/django-easy-tenants.svg)\n\nEste projeto tem como objetivo dar suporte a multiplos inquilinos para uma \naplicação django. \n \nNormalmente, existem três soluções para resolver o problema de multiplos inquilinos:\n\n1. Isolada: bancos de dados separados. Cada inquilino possui seu próprio banco de dados.\n2. Semi-Isolada: Banco de Dados Compartilhado, Esquemas Separados. Um banco de dados para todos os inquilinos, \nmas um esquema para cada inquilino.\n3. Compartilhada: banco de dados compartilhado, esquema compartilhado. \nTodos os inquilinos compartilham o mesmo banco de dados e esquema. Há uma tabela de inquilino principal, na qual \ntodas as outras tabelas têm uma chave estrangeira apontando para cada inquilino.\n\nEsta aplicação implementa a terceira solução, que em nossa opinião, é a melhor abordagem para suportar um número\ngrande de inquilinos.\n\nPara mais informações: [Building Multi Tenant Applications with Django\n](https://books.agiliq.com/projects/django-multi-tenant/en/latest/)\n\nSegue um exemplo de cada solução considerando 5000 inquilinos: \n\nSolução       | Quantidade DB | Quantidade Esquemas | Tempo de migração      | Acesso publico\n------------- | ------------- | ------------------- | ---------------------- | ---------------\nIsolada       | 5000          | 1 por DB            | demorado (1 x DB)      | Não\nSemi-Isolada  | 1             | 5000                | demorado (1 x esquema) | Sim\nCompartilhada | 1             | 1                   | rápido (1x)            | Sim\n\n\n## Como funciona\n![how to works](./screenshots/flux_easy_tenants.png) \n\n\n## Instalação\nÉ aconcelhavel fazer a instalação no inicio de um projeto. Em um projeto já existente,\ndepedendo da estrutura dos modelos, pode ser dificil a migração dos dados.\n\nAdicione `easy_tenant` em seu `INSTALLED_APPS` no settings.py:\n\n```python\nINSTALLED_APPS = [\n    ...,\n    \'easy_tenants\',\n]\n```\n   \nÉ preciso criar um modelo que será o inquilino da aplicação, em seus settings adicione \n`EASY_TENANTS_MODEL`:\n\n`yourapp/models.py`\n```python\nfrom easy_tenants.models import TenantMixin\n\nclass Customer(TenantMixin):\n    ...\n```\n\n`settings.py`\n```python\nEASY_TENANTS_MODEL = \'yourapp.CustomModel\'\n```\n\nSeus modelos que serão isolado por inquilino devem herdar de `TenantAbstract` e usar o manager `TenantManager`:\n\n```python\nfrom django.db import models\nfrom easy_tenants.models import TenantAbstract\nfrom easy_tenants.managers import TenantManager\n\nclass Product(TenantAbstract):\n    name = models.CharField(max_length=10)\n\n    objects = TenantManager()\n```\n\nÉ preciso definir o middleware `easy_tenants.middleware.DefaultTenantMiddleware` no settings:  \n_deve vir depois do `django.contrib.auth.middleware.AuthenticationMiddleware`_\n\n```python\nMIDDLEWARE = [\n    \'django.middleware.security.SecurityMiddleware\',\n    \'django.contrib.sessions.middleware.SessionMiddleware\',\n    \'django.middleware.common.CommonMiddleware\',\n    \'django.middleware.csrf.CsrfViewMiddleware\',\n    \'django.contrib.auth.middleware.AuthenticationMiddleware\',\n    \'django.contrib.messages.middleware.MessageMiddleware\',\n    \'django.middleware.clickjacking.XFrameOptionsMiddleware\',\n\n    \'easy_tenants.middleware.DefaultTenantMiddleware\',\n]\n```\n\nInclua a url:\n\n```python\npath(\'easy-tenants/\', include(\'easy_tenants.urls\')),\n```\n\nÉ preciso criar uma view que irá listar todos os seus tenants e depois incluir o nome\ndessa view no settings. Isso server para definir um tenant na sessão do usuário.\n\n\n`views.py`\n```python\nfrom django.shortcuts import render\n\ndef tenant_list(request):\n    user_tenants = request.user.tenants.all()\n    return render(request, \'tenant_list.html\', {\n        \'object_list\': user_tenants\n    })\n```\n\n`tenant_list.html`\n```html\n...\n<ul>\n  {% for object in object_list %}\n    <li>\n      <form action="{% url \'easy_tenants:set-current-tenant\' object.pk %}" method="post">\n        {% csrf_token %}\n        <button type="submit">Use {{ object.name }}</button>\n      </form>\n    </li>\n  {% endfor %}\n</ul>\n...\n```\n\n`urls.py`\n```python\npath(\'tenants/\', tenant_list, name=\'tenant-list\'),\n```\n\n`settings.py`\n```python\nEASY_TENANTS_LIST_URL = \'tenant-list\'\n```\n\nDepois de escolher o tenant, o usuário é redirecionado para uma url definida \nno settings `EASY_TENANTS_REDIRECT_URL`:\n\n`settings.py`\n```python\nEASY_TENANTS_REDIRECT_URL = \'home\'\n```  \n\n\nCaso não houver um tenant definido na sessão, toda url é é redirecionada para \n`EASY_TENANTS_LIST_URL`, se deseja ignorar algumas urls é possivel informar o nome\ndelas na configuração `EASY_TENANTS_IGNORE_URLS`, conforme o exemplo:\n\n```python\nEASY_TENANTS_IGNORE_URLS = [\n    \'admin:index\',\n    \'admin:login\',\n    \'namespace:url_name\',\n]\n```\n\nCaso queira separar os arquivos de upload por tenant, basta mudar a configuração `DEFAULT_FILE_STORAGE`\n(disponivel somente para arquivos locais):\n\n```python\nDEFAULT_FILE_STORAGE = \'easy_tenants.storage.TenantFileSystemStorage\'\n```\n\n\n## Excutar o projeto de exemplo\n```bash\npython manage.py migrate\npython manage.py createsuperuser\npython manage.py runserver\n```\nAcesse a pagina `/admin/`, crie um `Customer` e adicione o usuário a ele.\n\n## Inspiração\n[django-tenant-schemas](https://github.com/bernardopires/django-tenant-schemas)  \n[django-tenants](https://github.com/tomturner/django-tenants)  \n[django-scopes](https://github.com/raphaelm/django-scopes)  \n',
    'author': 'Cleiton Lima',
    'author_email': 'cleiton.limapin@gmail.com',
    'maintainer': None,
    'maintainer_email': None,
    'url': 'https://github.com/CleitonDeLima/django-easy-tenants',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.6',
}


setup(**setup_kwargs)
