Showing
32 changed files
with
720 additions
and
0 deletions
.gitignore
0 → 100644
1 | +*.log | ||
2 | + | ||
3 | +*.py[codt] | ||
4 | + | ||
5 | +# C extensions | ||
6 | +*.so | ||
7 | + | ||
8 | +# Packages | ||
9 | +*.egg | ||
10 | +*.egg-info | ||
11 | +dist | ||
12 | +build | ||
13 | +eggs | ||
14 | +parts | ||
15 | +bin | ||
16 | +var | ||
17 | +sdist | ||
18 | +develop-eggs | ||
19 | +.installed.cfg | ||
20 | +lib | ||
21 | +lib64 | ||
22 | +logs | ||
23 | + | ||
24 | +# Installer logs | ||
25 | +pip-log.txt | ||
26 | + | ||
27 | +# Unit test / coverage reports | ||
28 | +.coverage | ||
29 | +.tox | ||
30 | +nosetests.xml | ||
31 | +coverage.xml | ||
32 | +junit.xml | ||
33 | + | ||
34 | +# Translations | ||
35 | +*.mo | ||
36 | + | ||
37 | +# Mr Developer | ||
38 | +.mr.developer.cfg | ||
39 | +.project | ||
40 | +.pydevproject | ||
41 | + | ||
42 | +# Complexity | ||
43 | +output/*.html | ||
44 | +output/*/index.html | ||
45 | + | ||
46 | +# Sphinx | ||
47 | +docs/_build | ||
48 | + | ||
49 | +.webassets-cache | ||
50 | + | ||
51 | +# Virtualenvs | ||
52 | +venv | ||
53 | + | ||
54 | +# intellij | ||
55 | +*.ipr | ||
56 | +*.iml | ||
57 | +*.iws | ||
58 | + | ||
59 | +# vim | ||
60 | +*.sw[o,p] | ||
61 | + | ||
62 | +.DS_Store | ||
63 | + | ||
64 | +# node | ||
65 | +node_modules/ | ||
66 | + | ||
67 | +# bower packages | ||
68 | +.sass-cache/ | ||
69 | +.idea/.name | ||
70 | +.idea/scopes/scope_settings.xml | ||
71 | +.idea/encodings.xml | ||
72 | +.idea/workspace.xml | ||
73 | + | ||
74 | +# models | ||
75 | +models.png | ||
76 | + | ||
77 | +.idea/* | ||
78 | + | ||
79 | +*.db | ||
80 | + | ||
81 | +secret.key | ||
82 | + | ||
83 | +.bash_history | ||
84 | +.vagrant/* | ||
85 | + | ||
86 | +# Sublime Text 3 | ||
87 | +*.sublime-project | ||
88 | +*.sublime-workspace | ||
89 | + | ||
90 | +# ? | ||
91 | +.cache | ||
92 | +src | ||
93 | + | ||
94 | +# Configuration | ||
95 | +.env | ||
96 | + | ||
97 | +# Virtual Environment | ||
98 | +.venv | ||
99 | +tmp | ||
100 | +Procfile.dev | ||
101 | + | ||
102 | +# Cython .C files (precompilation) | ||
103 | +*.c | ||
104 | + | ||
105 | +__pycache__/ | ||
106 | + | ||
107 | +# Logs nginx | ||
108 | +deployment/logs/ | ||
109 | + | ||
110 | +.pytest_cache/ | ||
111 | + | ||
112 | +project/settings/production.py | ||
113 | +project/static/* | ||
114 | +project/media/* |
README.rst
0 → 100644
deployment/circus.ini
0 → 100644
1 | +[socket:PROJECT-NAME] | ||
2 | +host = 127.0.0.1 | ||
3 | +port = 8000 | ||
4 | + | ||
5 | +[watcher:PROJECT-NAME] | ||
6 | +cmd = /path/virtualenv/bin/chaussette | ||
7 | +args = --fd $(circus.sockets.PROJECT-NAME) PROJECT-NAME.wsgi.application | ||
8 | +use_sockets = True | ||
9 | +numprocesses = 3 | ||
10 | +autostart = True | ||
11 | + | ||
12 | +stdout_stream.class = FileStream | ||
13 | +stdout_stream.filename = /PATH/PROJECT/deployment/logs/circus-stdout.log | ||
14 | + | ||
15 | +stderr_stream.class = FileStream | ||
16 | +stderr_stream.filename = /PATH/PROJECT/deployment/logs/circus-stderr.log | ||
17 | + | ||
18 | + | ||
19 | +[env:PROJECT-NAME] | ||
20 | +PYTHONPATH = /PATH/SOURCE/PROJECT-NAME/ |
deployment/nginx.conf
0 → 100644
1 | +server { | ||
2 | + listen 80; | ||
3 | + charset utf-8; | ||
4 | + server_name URL-PROJECT-NAME; | ||
5 | + return 301 https://$host$request_uri; | ||
6 | +} | ||
7 | + | ||
8 | +server { | ||
9 | + listen 443; | ||
10 | + charset utf-8; | ||
11 | + server_name URL-PROJECT-NAME; | ||
12 | + client_max_body_size 4G; | ||
13 | + | ||
14 | + ssl on; | ||
15 | + ssl_certificate /etc/letsencrypt/live/URL-PROJECT-NAME/fullchain.pem; | ||
16 | + ssl_certificate_key /etc/letsencrypt/live/URL-PROJECT-NAME/privkey.pem; | ||
17 | + | ||
18 | + | ||
19 | + location /static/ { | ||
20 | + # autoindex off; | ||
21 | + alias /PATH/PROJECT/PROJECT-NAME/static/; | ||
22 | + } | ||
23 | + | ||
24 | + location /media/ { | ||
25 | + # autoindex off; | ||
26 | + alias /PATH/PROJECT/PROJECT-NAME/media/; | ||
27 | + } | ||
28 | + | ||
29 | + location / { | ||
30 | + proxy_pass http://localhost:8000; | ||
31 | + proxy_set_header X-Forwarded-Host $server_name; | ||
32 | + proxy_set_header X-Real-IP $remote_addr; | ||
33 | + proxy_set_header Host $host; | ||
34 | + proxy_set_header X-Scheme $scheme; | ||
35 | + proxy_connect_timeout 600; | ||
36 | + proxy_send_timeout 600; | ||
37 | + proxy_read_timeout 600; | ||
38 | + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||
39 | + add_header P3P 'CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"'; | ||
40 | + } | ||
41 | + | ||
42 | + ## Logs | ||
43 | + access_log /PATH/PROJECT/deployment/logs/nginx-access.log; | ||
44 | + error_log /PATH/PROJECT/deployment/logs/nginx-errors.log; | ||
45 | + | ||
46 | +} |
env.example
0 → 100644
1 | +# General settings | ||
2 | +DJANGO_DEBUG=true | ||
3 | +DJANGO_SECRET_KEY=CHANGEME!!! | ||
4 | +DJANGO_ALLOWED_HOSTS=*,127.0.0.1 | ||
5 | + | ||
6 | +# Database | ||
7 | +DATABASE_URL=postgres://dbuser:dbpass@localhost:port/mydb | ||
8 | +# SQLite | ||
9 | +# DATABASE_URL=sqlite:///mydb.db | ||
10 | + | ||
11 | +# Security! Better to use DNS for this task, but you can use redirect | ||
12 | +DJANGO_SECURE_SSL_REDIRECT=False | ||
13 | + | ||
14 | + | ||
15 | +# Facebook configuration | ||
16 | +SOCIAL_AUTH_FACEBOOK_KEY=<your app id goes here> | ||
17 | +SOCIAL_AUTH_FACEBOOK_SECRET=<your app secret goes here> | ||
18 | + | ||
19 | +PROJECT_NAME_HEADER=Name Project | ||
20 | +PROJECT_NAME_TITLE=Name Project | ||
21 | + | ||
22 | +ACTIVAR_HERRAMIENTAS_DEBBUGING=false |
manage.py
0 → 100644
1 | +#!/usr/bin/env python | ||
2 | +import os | ||
3 | +import sys | ||
4 | + | ||
5 | +if __name__ == "__main__": | ||
6 | + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings.base") | ||
7 | + try: | ||
8 | + from django.core.management import execute_from_command_line | ||
9 | + except ImportError as exc: | ||
10 | + raise ImportError( | ||
11 | + "Couldn't import Django. Are you sure it's installed and " | ||
12 | + "available on your PYTHONPATH environment variable? Did you " | ||
13 | + "forget to activate a virtual environment?" | ||
14 | + ) from exc | ||
15 | + execute_from_command_line(sys.argv) |
project/__init__.py
0 → 100644
project/apps/__init__.py
0 → 100644
project/apps/core/__init__.py
0 → 100644
project/apps/core/admin.py
0 → 100644
1 | +from django.contrib import admin | ||
2 | +from django.utils import timezone | ||
3 | +from django.utils.translation import gettext as _ | ||
4 | + | ||
5 | +from . import filters | ||
6 | + | ||
7 | + | ||
8 | +class PublicadoAdmin(admin.ModelAdmin): | ||
9 | + actions = ['publicar', 'no_publicar'] | ||
10 | + | ||
11 | + def publicar(self, request, queryset): | ||
12 | + updated_records = queryset.update(publicado=timezone.now()) | ||
13 | + message = _('updated records %s' % updated_records) | ||
14 | + self.message_user(request, message) | ||
15 | + | ||
16 | + publicar.short_description = 'Publicar los registros seleccionados' | ||
17 | + | ||
18 | + def no_publicar(self, request, queryset): | ||
19 | + registros_actualizados = queryset.update(publicado=None) | ||
20 | + mensaje = f'Registros actualizados {registros_actualizados}' | ||
21 | + self.message_user(request, mensaje) | ||
22 | + | ||
23 | + no_publicar.short_description = 'No publicar los registros seleccionados' | ||
24 | + | ||
25 | + def get_list_display(self, request): | ||
26 | + return list(super().get_list_display(request)) + ['publicado'] | ||
27 | + | ||
28 | + def get_list_filter(self, request): | ||
29 | + list_filter = [filters.PublicadoListFilter] + list(super().get_list_filter(request)) | ||
30 | + return list_filter |
project/apps/core/apps.py
0 → 100644
project/apps/core/filters.py
0 → 100644
1 | +from django.contrib import admin | ||
2 | +from django.utils.translation import gettext as _ | ||
3 | + | ||
4 | + | ||
5 | +# Filters Admin | ||
6 | + | ||
7 | +class PublicadoListFilter(admin.SimpleListFilter): | ||
8 | + title = 'Publicado' | ||
9 | + | ||
10 | + # Parameter for the filter that will be used in the URL query. | ||
11 | + parameter_name = 'publicado' | ||
12 | + | ||
13 | + def lookups(self, request, model_admin): | ||
14 | + return ( | ||
15 | + ('true', 'Publicados'), | ||
16 | + ('false', 'No Publicados'), | ||
17 | + ) | ||
18 | + | ||
19 | + def queryset(self, request, queryset): | ||
20 | + value = self.value() | ||
21 | + if value: | ||
22 | + return queryset.exclude(publicado__isnull=value == 'true') | ||
23 | + | ||
24 | + return queryset.all() | ||
25 | + | ||
26 | + | ||
27 | +# DRF Filter Common. | ||
28 | +def filter_unaccent_contains(queryset, name, value): | ||
29 | + # TODO: add unaccent within the join list. | ||
30 | + lookup = '__'.join([name, 'icontains']) | ||
31 | + return queryset.filter(**{lookup: value}) |
project/apps/core/migrations/__init__.py
0 → 100644
project/apps/core/models.py
0 → 100644
1 | +from django.db import models | ||
2 | +from django.utils import timezone | ||
3 | + | ||
4 | +from .querysets import PublicadoQuerySet | ||
5 | + | ||
6 | + | ||
7 | +class Publicado(models.Model): | ||
8 | + class Meta: | ||
9 | + abstract = True | ||
10 | + | ||
11 | + publicado = models.DateTimeField(blank=True, null=True) | ||
12 | + | ||
13 | + objects = PublicadoQuerySet.as_manager() | ||
14 | + | ||
15 | + def publicar(self, estado=True): | ||
16 | + self.publicado = timezone.now() if estado else None | ||
17 | + self.save(update_fields=('publicado',)) |
project/apps/core/paginations.py
0 → 100644
project/apps/core/querysets.py
0 → 100644
project/apps/core/tests.py
0 → 100644
project/apps/core/tests/__init__.py
0 → 100644
project/apps/core/tests/fixtures.py
0 → 100644
1 | +import json | ||
2 | + | ||
3 | +import pytest | ||
4 | + | ||
5 | +from django.contrib.auth import get_user_model | ||
6 | +from oauth2_provider.models import get_application_model | ||
7 | +from rest_framework.test import APIClient | ||
8 | + | ||
9 | +User = get_user_model() | ||
10 | + | ||
11 | +CONTENT_TYPE_JSON = 'application/json' | ||
12 | + | ||
13 | + | ||
14 | +@pytest.fixture | ||
15 | +def create_user(username, first_name='Admin', last_name='Root', email=None): | ||
16 | + user, created = User.objects.get_or_create( | ||
17 | + username=username, | ||
18 | + email='{}@root.com'.format(username) if email is None else email, | ||
19 | + defaults=dict( | ||
20 | + first_name=first_name, | ||
21 | + last_name=last_name, | ||
22 | + password='password' | ||
23 | + ) | ||
24 | + ) | ||
25 | + | ||
26 | + return user | ||
27 | + | ||
28 | + | ||
29 | +@pytest.fixture | ||
30 | +def get_default_test_user(): | ||
31 | + test_user = create_user(username='test_user', first_name='Test', last_name='User', email='test@user') | ||
32 | + return test_user | ||
33 | + | ||
34 | + | ||
35 | +def get_client_application(): | ||
36 | + Application = get_application_model() | ||
37 | + application, _ = Application.objects.get_or_create( | ||
38 | + name='TestApp', | ||
39 | + client_type=Application.CLIENT_CONFIDENTIAL, | ||
40 | + authorization_grant_type=Application.GRANT_CLIENT_CREDENTIALS, | ||
41 | + skip_authorization=True | ||
42 | + ) | ||
43 | + | ||
44 | + return application | ||
45 | + | ||
46 | + | ||
47 | +def client_authorized(): | ||
48 | + app = get_client_application() | ||
49 | + client = APIClient() | ||
50 | + r = client.post('/oauth2/token/', { | ||
51 | + 'grant_type': 'client_credentials', | ||
52 | + 'client_id': app.client_id, | ||
53 | + 'client_secret': app.client_secret | ||
54 | + }) | ||
55 | + response = json.loads(r.content) | ||
56 | + client = APIClient() | ||
57 | + client.credentials(HTTP_AUTHORIZATION='Bearer ' + response['access_token']) | ||
58 | + return client |
project/apps/core/tests/utils.py
0 → 100644
1 | +import json | ||
2 | + | ||
3 | +from django.contrib.auth import get_user_model | ||
4 | +from rest_framework.test import APIClient | ||
5 | + | ||
6 | +from .fixtures import create_user | ||
7 | + | ||
8 | +JSON_CONTENT_TYPE = "application/json" | ||
9 | +JSON_API_CONTENT_TYPE = "application/vnd.api+json" | ||
10 | +JSON_API_ACCEPT_HEADER = "application/vnd.api+json" | ||
11 | + | ||
12 | + | ||
13 | +def get_authenticated_client(user=None): | ||
14 | + client = APIClient() | ||
15 | + if user is not None: | ||
16 | + client.force_authenticate(user=user) | ||
17 | + return client | ||
18 | + | ||
19 | + | ||
20 | +def get(url, params=None, headers=None, user_logged=None): | ||
21 | + url += "?{}".format(params) if params else '' | ||
22 | + client = get_authenticated_client(user_logged) | ||
23 | + if headers is None: | ||
24 | + headers = {'HTTP_ACCEPT': JSON_API_ACCEPT_HEADER} | ||
25 | + | ||
26 | + response = client.get(url, **headers) | ||
27 | + return response | ||
28 | + | ||
29 | + | ||
30 | +def post(url, data=None, content_type=JSON_API_CONTENT_TYPE, headers=None, user_logged=None): | ||
31 | + url = url + '/' if not url.endswith('/') else url | ||
32 | + client = get_authenticated_client(user_logged) | ||
33 | + if headers is None: | ||
34 | + headers = {'HTTP_ACCEPT': JSON_API_ACCEPT_HEADER} | ||
35 | + | ||
36 | + response = client.post(url, data=json.dumps(data), content_type=content_type, **headers) | ||
37 | + return response | ||
38 | + | ||
39 | + | ||
40 | +def patch(url, data=None, content_type=JSON_API_CONTENT_TYPE, headers=None, user_logged=None): | ||
41 | + url = url + '/' if not url.endswith('/') else url | ||
42 | + client = get_authenticated_client(user_logged) | ||
43 | + if headers is None: | ||
44 | + headers = {'HTTP_ACCEPT': JSON_API_ACCEPT_HEADER} | ||
45 | + | ||
46 | + response = client.patch(url, data=json.dumps(data), content_type=content_type, **headers) | ||
47 | + return response | ||
48 | + | ||
49 | + | ||
50 | +def delete(url, data=None, content_type=JSON_API_CONTENT_TYPE, headers=None, user_logged=None): | ||
51 | + url = url + '/' if not url.endswith('/') else url | ||
52 | + client = get_authenticated_client(user_logged) | ||
53 | + if headers is None: | ||
54 | + headers = {'HTTP_ACCEPT': JSON_API_ACCEPT_HEADER} | ||
55 | + | ||
56 | + response = client.delete(url, data=json.dumps(data), content_type=content_type, **headers) | ||
57 | + return response |
project/apps/core/views.py
0 → 100644
project/router.py
0 → 100644
project/settings/__init__.py
0 → 100644
project/settings/base.py
0 → 100644
1 | +import sys | ||
2 | + | ||
3 | +import environ | ||
4 | +import os | ||
5 | + | ||
6 | +from django.utils.translation import gettext_lazy as _ | ||
7 | + | ||
8 | + | ||
9 | +ROOT_DIR = environ.Path(__file__) - 3 | ||
10 | +PROJECT_DIR = ROOT_DIR.path('project') | ||
11 | +APPS_DIR = PROJECT_DIR.path('apps') | ||
12 | + | ||
13 | +sys.path.insert(0, str(APPS_DIR)) | ||
14 | + | ||
15 | +# Load operating system environment variables and then prepare to use them | ||
16 | +env = environ.Env() | ||
17 | +# patch for https://github.com/joke2k/django-environ/issues/119 | ||
18 | +env_file = str(ROOT_DIR.path('.env')) | ||
19 | +env.read_env(env_file) | ||
20 | + | ||
21 | +# PROJECT | ||
22 | +PROJECT_NAME_HEADER = env('PROJECT_NAME_HEADER', default='Project Name') | ||
23 | +PROJECT_NAME_TITLE = env('PROJECT_NAME_TITLE', default='Project Name') | ||
24 | + | ||
25 | +# DEBUG | ||
26 | +# ------------------------------------------------------------------------------ | ||
27 | +# See: https://docs.djangoproject.com/en/dev/ref/settings/#debug | ||
28 | +DEBUG = env.bool('DJANGO_DEBUG', False) | ||
29 | + | ||
30 | +SECRET_KEY = env('DJANGO_SECRET_KEY', default='CHANGEME!!!') # noqa | ||
31 | +ALLOWED_HOSTS = env.list('DJANGO_ALLOWED_HOSTS', default='*') # noqa | ||
32 | + | ||
33 | +DATABASES = { | ||
34 | + 'default': { | ||
35 | + 'ENGINE': os.environ.get('POSTGRES_ENGINE'), | ||
36 | + 'NAME': os.environ.get('POSTGRES_DB'), | ||
37 | + 'USER': os.environ.get('POSTGRES_USER'), | ||
38 | + 'PASSWORD': os.environ.get('POSTGRES_PASSWORD'), | ||
39 | + 'HOST': os.environ.get('POSTGRES_HOST'), | ||
40 | + 'PORT': os.environ.get('POSTGRES_PORT'), | ||
41 | + } | ||
42 | +} | ||
43 | + | ||
44 | + | ||
45 | +DJANGO_APPS = ( | ||
46 | + 'django.contrib.admin', | ||
47 | + 'django.contrib.auth', | ||
48 | + 'django.contrib.contenttypes', | ||
49 | + 'django.contrib.sessions', | ||
50 | + 'django.contrib.messages', | ||
51 | + 'django.contrib.staticfiles', | ||
52 | +) | ||
53 | + | ||
54 | +THIRD_PARTY_APPS = ( | ||
55 | + 'rest_framework', | ||
56 | + 'django_filters', | ||
57 | + 'corsheaders', | ||
58 | +) | ||
59 | + | ||
60 | +PROJECT_APPS = ( | ||
61 | + 'core', | ||
62 | +) | ||
63 | + | ||
64 | +INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + PROJECT_APPS | ||
65 | + | ||
66 | +MIDDLEWARE = ( | ||
67 | + 'corsheaders.middleware.CorsMiddleware', | ||
68 | + 'django.middleware.security.SecurityMiddleware', | ||
69 | + 'django.contrib.sessions.middleware.SessionMiddleware', | ||
70 | + 'django.middleware.common.CommonMiddleware', | ||
71 | + 'django.middleware.csrf.CsrfViewMiddleware', | ||
72 | + 'django.contrib.auth.middleware.AuthenticationMiddleware', | ||
73 | + 'django.contrib.messages.middleware.MessageMiddleware', | ||
74 | + 'django.middleware.clickjacking.XFrameOptionsMiddleware', | ||
75 | + | ||
76 | +) | ||
77 | + | ||
78 | +ROOT_URLCONF = 'project.urls' | ||
79 | + | ||
80 | +# Python dotted path to the WSGI application used by Django's runserver. | ||
81 | +WSGI_APPLICATION = 'project.wsgi.application' | ||
82 | + | ||
83 | +LANGUAGE_CODE = 'es-ar' | ||
84 | +TIME_ZONE = 'America/Argentina/Catamarca' | ||
85 | +USE_I18N = True | ||
86 | +USE_L10N = True | ||
87 | +USE_TZ = True | ||
88 | + | ||
89 | +LANGUAGES = [ | ||
90 | + ('es', _('Español')), | ||
91 | + ('en', _('English')), | ||
92 | +] | ||
93 | + | ||
94 | +# Static files (CSS, JavaScript, Images) | ||
95 | +# https://docs.djangoproject.com/en/1.7/howto/static-files/ | ||
96 | + | ||
97 | +STATIC_ROOT = str(PROJECT_DIR.path('static')) | ||
98 | +STATIC_URL = '/static/' | ||
99 | + | ||
100 | +MEDIA_ROOT = str(PROJECT_DIR.path('media')) | ||
101 | +MEDIA_URL = env.str('MEDIA_URL', default='/media/') | ||
102 | + | ||
103 | +CORS_ORIGIN_ALLOW_ALL = True | ||
104 | + | ||
105 | +TEMPLATES = [ | ||
106 | + { | ||
107 | + 'BACKEND': 'django.template.backends.django.DjangoTemplates', | ||
108 | + 'DIRS': [str(PROJECT_DIR.path('templates'))], | ||
109 | + 'APP_DIRS': True, | ||
110 | + 'OPTIONS': { | ||
111 | + 'debug': DEBUG, | ||
112 | + 'context_processors': [ | ||
113 | + 'django.template.context_processors.debug', | ||
114 | + 'django.template.context_processors.request', | ||
115 | + 'django.contrib.auth.context_processors.auth', | ||
116 | + 'django.contrib.messages.context_processors.messages', | ||
117 | + ], | ||
118 | + }, | ||
119 | + }, | ||
120 | +] | ||
121 | + | ||
122 | +LOGIN_URL = '/admin/login/' | ||
123 | + | ||
124 | +# Password validation | ||
125 | +# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators | ||
126 | + | ||
127 | +AUTH_PASSWORD_VALIDATORS = [ | ||
128 | + { | ||
129 | + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', | ||
130 | + }, | ||
131 | + { | ||
132 | + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', | ||
133 | + }, | ||
134 | + { | ||
135 | + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', | ||
136 | + }, | ||
137 | + { | ||
138 | + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', | ||
139 | + }, | ||
140 | +] | ||
141 | + | ||
142 | + | ||
143 | +AUTHENTICATION_BACKENDS = ( | ||
144 | + 'django.contrib.auth.backends.ModelBackend', | ||
145 | +) | ||
146 | + | ||
147 | +REST_FRAMEWORK = { | ||
148 | + 'PAGE_SIZE': 50, | ||
149 | + 'EXCEPTION_HANDLER': 'rest_framework_json_api.exceptions.exception_handler', | ||
150 | + 'DEFAULT_PAGINATION_CLASS': 'core.paginations.LargePagination', | ||
151 | + 'DEFAULT_PARSER_CLASSES': ( | ||
152 | + 'rest_framework_json_api.parsers.JSONParser', | ||
153 | + 'rest_framework.parsers.FormParser', | ||
154 | + 'rest_framework.parsers.MultiPartParser' | ||
155 | + ), | ||
156 | + 'DEFAULT_AUTHENTICATION_CLASSES': ( | ||
157 | + 'oauth2_provider.contrib.rest_framework.OAuth2Authentication', | ||
158 | + 'rest_framework.authentication.BasicAuthentication', | ||
159 | + 'rest_framework.authentication.SessionAuthentication', | ||
160 | + ), | ||
161 | + 'DEFAULT_RENDERER_CLASSES': ('rest_framework_json_api.renderers.JSONRenderer', | ||
162 | + 'rest_framework.renderers.BrowsableAPIRenderer'), | ||
163 | + 'DEFAULT_FILTER_BACKENDS': ( | ||
164 | + 'rest_framework_json_api.filters.QueryParameterValidationFilter', | ||
165 | + 'rest_framework_json_api.filters.OrderingFilter', | ||
166 | + 'rest_framework_json_api.django_filters.DjangoFilterBackend', | ||
167 | + 'rest_framework.filters.SearchFilter', | ||
168 | + ), | ||
169 | + 'SEARCH_PARAM': 'filter[search]', | ||
170 | + 'DEFAULT_METADATA_CLASS': 'rest_framework_json_api.metadata.JSONAPIMetadata', | ||
171 | + 'TEST_REQUEST_RENDERER_CLASSES': ( | ||
172 | + 'rest_framework_json_api.renderers.JSONRenderer', | ||
173 | + 'rest_framework.renderers.MultiPartRenderer', | ||
174 | + ), | ||
175 | + 'TEST_REQUEST_DEFAULT_FORMAT': 'vnd.api+json', | ||
176 | + | ||
177 | +} | ||
178 | + | ||
179 | + | ||
180 | +ACTIVAR_HERRAMIENTAS_DEBBUGING = env.bool('ACTIVAR_HERRAMIENTAS_DEBBUGING', default=False) | ||
181 | + | ||
182 | +if ACTIVAR_HERRAMIENTAS_DEBBUGING: | ||
183 | + INSTALLED_APPS += ( | ||
184 | + 'debug_toolbar', | ||
185 | + 'django_extensions', | ||
186 | + ) | ||
187 | + | ||
188 | + MIDDLEWARE += ('debug_toolbar.middleware.DebugToolbarMiddleware',) |
project/settings/testing.py
0 → 100644
project/urls.py
0 → 100644
1 | +"""portal URL Configuration | ||
2 | + | ||
3 | +The `urlpatterns` list routes URLs to views. For more information please see: | ||
4 | + https://docs.djangoproject.com/en/2.0/topics/http/urls/ | ||
5 | +Examples: | ||
6 | +Function views | ||
7 | + 1. Add an import: from my_app import views | ||
8 | + 2. Add a URL to urlpatterns: path('', views.home, name='home') | ||
9 | +Class-based views | ||
10 | + 1. Add an import: from other_app.views import Home | ||
11 | + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') | ||
12 | +Including another URLconf | ||
13 | + 1. Import the include() function: from django.urls import include, path | ||
14 | + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) | ||
15 | +""" | ||
16 | +from django.contrib import admin | ||
17 | +from django.urls import path, include | ||
18 | +from django.conf import settings | ||
19 | + | ||
20 | +from .router import router | ||
21 | + | ||
22 | +# I added platform's name. | ||
23 | +admin.site.site_header = getattr(settings, 'PROJECT_NAME_HEADER') | ||
24 | +admin.site.site_title = getattr(settings, 'PROJECT_NAME_TITLE') | ||
25 | + | ||
26 | +urlpatterns = [ | ||
27 | + path('admin/', admin.site.urls), | ||
28 | + path('api/v1/', include(router.urls)), | ||
29 | +] |
project/wsgi.py
0 → 100644
1 | +""" | ||
2 | +WSGI config for portal project. | ||
3 | + | ||
4 | +It exposes the WSGI callable as a module-level variable named ``application``. | ||
5 | + | ||
6 | +For more information on this file, see | ||
7 | +https://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/ | ||
8 | +""" | ||
9 | + | ||
10 | +import os | ||
11 | +from os.path import abspath, dirname | ||
12 | +from sys import path | ||
13 | + | ||
14 | +from django.core.wsgi import get_wsgi_application | ||
15 | + | ||
16 | +SITE_ROOT = dirname(dirname(abspath(__file__))) | ||
17 | +path.append(SITE_ROOT) | ||
18 | + | ||
19 | +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings.base") | ||
20 | + | ||
21 | +application = get_wsgi_application() |
pytest.ini
0 → 100644
requirements/base.txt
0 → 100644
1 | +# Requeriments base. | ||
2 | + | ||
3 | +Django==4.2.9 | ||
4 | +django-cors-headers==4.3.0 | ||
5 | +django-filter==23.3 | ||
6 | +djangorestframework==3.14.0 | ||
7 | +django-environ==0.11.2 | ||
8 | +djangorestframework-jsonapi==6.1.0 | ||
9 | +django-oauth-toolkit==2.3.0 | ||
10 | +mozilla-django-oidc==3.0.0 | ||
11 | + | ||
12 | + | ||
13 | +# database | ||
14 | +psycopg2==2.9.9 | ||
15 | +psycopg2-binary==2.9.9 |
requirements/development.txt
0 → 100644
requirements/production.txt
0 → 100644
requirements/testing.txt
0 → 100644
-
Please register or login to post a comment