Skip to content

Commit

Permalink
Feature: Major 2024 update
Browse files Browse the repository at this point in the history
  • Loading branch information
pedroKpaxo committed Sep 26, 2024
1 parent 841ac63 commit bfde916
Show file tree
Hide file tree
Showing 13 changed files with 165 additions and 86 deletions.
9 changes: 9 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Django Base Monumento Pull Request

### What I did:

- <thing I’ve done>
- <detailing>

### How to test:

125 changes: 71 additions & 54 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,44 @@
# OilDjango-Pro [![build](https://github.com/MonumentoSoftware/django-base/actions/workflows/main.yml/badge.svg?branch=main)](https://github.com/MonumentoSoftware/django-base/actions/workflows/main.yml)

For professional managament of energy industries assets

## Como rodar

Se for a primeira vez:
# Django Base [![build](https://github.com/MonumentoSoftware/django-base/actions/workflows/main.yml/badge.svg?branch=main)](https://github.com/MonumentoSoftware/django-base/actions/workflows/main.yml)

A clean and simple Django project template.
Used as a base for Monumento Software OilDjangoPro

- [Django Base ](#django-base-)
- [Install](#install)
- [Usage](#usage)
- [Database seed](#database-seed)
- [Documentação da API](#documentação-da-api)
- [Interface gráfica](#interface-gráfica)
- [Incrementando a documentação](#incrementando-a-documentação)
- [Unit Testing](#unit-testing)
- [Test Coverage](#test-coverage)
- [Architecture](#architecture)
- [Useful Commands](#useful-commands)
- [Create an app](#create-an-app)
- [Enter a container](#enter-a-container)
- [Open the Django shell](#open-the-django-shell)
- [Reset the database](#reset-the-database)
- [Update translations from English](#update-translations-from-english)

# Install

Basic installation:
```bash
make setup_install
```
You can also create a virtual environment:

Depois, apenas:
```bash
make up
make setup_venv
```

### Opcional

Criar ambiente virtual:
# Usage
To start the project, run the following command:
```bash
make setup_venv
make up
```
## Database seed

Rodar seed do banco:
Seed the database:
```bash
make seed
```
Expand All @@ -30,73 +47,73 @@ make seed

### Interface gráfica

Usamos a Swagger UI, para exibir a documentação, em formato OpenAPI, numa interface gráfica no navegador. Para rodar localmente apenas o container da documentação, seguir os passos:
We use Swagger UI to document the API. To access it, follow the steps:

1. Rodar `docker-compose up swagger-ui`
2. Acessar *localhost:8080*
1. Run the project with `make up`.
2. Access `http://localhost:8000/swagger/`.

### Incrementando a documentação

O arquivo *docs/openapi.json* descreve a API utilizando a especificação OpenAPI. Ele deve ser editado manualmente ao longo do tempo de vida do projeto para deixar a documentação em conformidade com a API. Uma ferramenta que pode acelerar este processo é o comando *genarateschema* do Django REST Framework. Ele pode ser usado para gerar a documentação automática do projeto baseada nas views existentes. No entanto, deve-se ter cuidado pra não sobrescrever o arquivo original *openapi.json*. Para utilizar a ferramenta, seguir o tutorial:
The file *docs/openapi.json* describes the API using the OpenAPI specification. It must be manually edited over the project's lifetime to keep the documentation in compliance with the API. A tool that can speed up this process is the *generateschema* command from Django REST Framework. It can be used to generate the project's automatic documentation based on the existing views. However, care must be taken not to overwrite the original *openapi.json* file. To use the tool, follow the tutorial:

1. Rodar o comando `make generate_schema` para criar o arquivo **docs/temp-schema.json**.
2. Identificar no arquivo gerado a parte desejada (exemplo: alguma *view* nova) e mover para **docs/openapi.json**.
3. Excluir o arquivo **docs/temp-schema.json**.
1. Run the command `make generate_schema` to create the file **docs/temp-schema.json**.
2. Identify the desired part in the generated file (e.g., some new *view*) and move it to **docs/openapi.json**.
3. Delete the file **docs/temp-schema.json**.

## Testes unitários
## Unit Testing

Utilizamos a biblioteca **pytest** para rodar testes unitários. Seu arquivo de configuração é *pytest.ini*.
We use the **pytest** library to run unit tests. Its configuration file is *pytest.ini*.

- Para rodas os testes, usar o comando `make test`.
- To run the tests, use the command `make test`.

Como por padrão os testes reutilizam o banco de dados gerado, caso tenha novas migrações é necessário re-criar o banco.
Since tests reuse the generated database by default, if there are new migrations, it is necessary to recreate the database.

- Para re-criar o banco, utilizar o comando `pytest --create-db`.
- To recreate the database, use the command `pytest --create-db`.

### Cobertura de teste
### Test Coverage

- `make coverage`

ou
or

- `make coverage_html`, para um relatório HTML.
- `make coverage_html`, for an HTML report.

## Arquitetura
## Architecture

- `apps`: aqui devem estar todas as django apps locais que devem ser criadas ao longo do desenvolvimento do projeto. No projeto base esta pasta conterá apenas a app `user` (e a `tenant`, se for um projeto tenant-based). Para criar uma nova app, deve-se usar o comando *make startapp* na raiz do projeto para criá-la no lugar correto e seguindo o template do projeto base.
- `conf`: módulo que contém arquivos de configuração do projeto.
- `app_template`: template usado para criação de novas apps. Geralmente, não deve ser alterado.
- `settings`: pasta com os arquivos settings do django. É modularizado de forma a possuir um arquivo de settings para cada ambiente: local, production, etc.
- `urls.py`: arquivo de urls do projeto. É preferível deixar apenas incluir as urls das outras apps, deixando a configuração específica de cada módulo em seu próprio arquivo urls.py.
- `wsgi.py`: arquivo wsgi padrão do Django para deploy.
- `docs`: módulo que contém arquivos relacionados à documentação do projeto.
- `openapi.json`: arquivo contendo schema da API REST. É usado no container *swagger-ui*.
- `lib`: módulo que contém as classes que devem ser compartilhada por todo o projeto, como por exemplo um model base, uma view genérica, etc.
- `models.py`: contém models base para o projeto que automaticamente incluem campos de timestamp (created_at ou updated_at) ou safe delete feature.
- `requirements`: contém as dependências do projeto, separadas por ambiente (local, production, etc.).
- `scripts`: contém shell scripts úteis para o projeto.
- `env.example`: arquivo env de exemplo para iniciar o projeto. Deve ser copiado para um arquivo `.env` (não versionado).
- `docker-compose.yml` e `Dockerfile`: arquivos de configuração Docker.
- `Makefile`: contém comandos úteis, como por exemplo entrar num container ou criar uma app.
- `apps`: here should be all the local Django apps that should be created throughout the project's development. In the base project, this folder will only contain the `user` app (and the `tenant`, if it is a tenant-based project). To create a new app, use the *make startapp* command at the project's root to create it in the correct place and following the base project's template.
- `conf`: module containing the project's configuration files.
- `app_template`: template used for creating new apps. Generally, it should not be altered.
- `settings`: folder with Django settings files. It is modularized to have a settings file for each environment: local, production, etc.
- `urls.py`: project's URL file. It is preferable to only include the URLs of other apps, leaving the specific configuration of each module in its own urls.py file.
- `wsgi.py`: standard Django WSGI file for deployment.
- `docs`: module containing files related to the project's documentation.
- `openapi.json`: file containing the REST API schema. It is used in the *swagger-ui* container.
- `lib`: module containing classes that should be shared throughout the project, such as a base model, a generic view, etc.
- `models.py`: contains base models for the project that automatically include timestamp fields (created_at or updated_at) or safe delete feature.
- `requirements`: contains the project's dependencies, separated by environment (local, production, etc.).
- `scripts`: contains useful shell scripts for the project.
- `env.example`: example env file to start the project. It should be copied to a `.env` file (not versioned).
- `docker-compose.yml` and `Dockerfile`: Docker configuration files.
- `Makefile`: contains useful commands, such as entering a container or creating an app.

## Comandos úteis
## Useful Commands

### Criar uma app
### Create an app

`make startapp [app_name]`

### Entrar em um container
### Enter a container

`make enter [service_name]`

### Abrir o django shell
### Open the Django shell

`make shell`

### Resetar o banco de dados
### Reset the database

`make reset_db`
`make reset_schema`

### Atualizar traduções do inglês
### Update translations from English

`make compilemessages`
`make compilemessages`
1 change: 0 additions & 1 deletion apps/conftest.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import pytest
from model_bakery import baker

from django.contrib.auth import get_user_model

Expand Down
8 changes: 4 additions & 4 deletions apps/user/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Generated by Django 3.2 on 2022-10-19 00:46
# Generated by Django 5.0 on 2024-09-26 23:20

import apps.user.managers
import apps.user.models
from django.db import migrations, models
import django.utils.timezone
import model_utils.fields
from django.db import migrations, models


class Migration(migrations.Migration):
Expand All @@ -30,8 +30,8 @@ class Migration(migrations.Migration):
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
('picture', models.ImageField(blank=True, null=True, upload_to=apps.user.models.user_picture_bucket, verbose_name='profile picture')),
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')),
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')),
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')),
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')),
],
options={
'verbose_name': 'user',
Expand Down
38 changes: 38 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@

- [26/09/2024](#26092024)
- [Django 5.0](#django-50)
- [Storages](#storages)
- [Django REST Framework 3.15.2](#django-rest-framework-3152)
- [Updated dependencies](#updated-dependencies)

# 26/09/2024

Major Update.

## Django 5.0
We updated Django to version 5.0. This update brings new features and improvements to the project.

### Storages
Some settings were updated to use the new storages configuration.
Now we have:
```python
# Default STORAGES from Django documentation
# See:
# https://docs.djangoproject.com/en/5.0/ref/settings/#std-setting-STORAGES
STORAGES = {
"default": {"BACKEND": "django.core.files.storage.FileSystemStorage"},
"staticfiles": {"BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage"},
}
```

## Django REST Framework 3.15.2
We updated Django REST Framework to version 3.15.2.
It solves some issues with the collect static command.

## Updated dependencies
Django==5.0
boto3==1.35.28
django-simple-history==3.7.0
djangorestframework==3.15.2
model-bakery==1.19.5

25 changes: 17 additions & 8 deletions conf/settings/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
env = environ.Env()

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
BASE_DIR = os.path.dirname(os.path.dirname(
os.path.dirname(os.path.abspath(__file__))))

# A simple slug name for the deploy environment
STAGE = env.str('STAGE', None)
Expand Down Expand Up @@ -59,6 +60,7 @@
'anymail',
'corsheaders',
'django_extensions',
'django_filters',
'rest_framework',
'rest_framework.authtoken',
'djoser',
Expand All @@ -71,7 +73,6 @@
]



INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS

MIDDLEWARE = [
Expand Down Expand Up @@ -161,15 +162,27 @@


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/
# https://docs.djangoproject.com/en/5.0/howto/static-files/

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]

# Storages

# Default STORAGES from Django documentation
# See:
# https://docs.djangoproject.com/en/5.0/ref/settings/#std-setting-STORAGES
STORAGES = {
"default": {"BACKEND": "django.core.files.storage.FileSystemStorage"},
"staticfiles": {"BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage"},
}

# Use ManifestStaticFilesStorage when not in debug mode
if not DEBUG:
STORAGES['staticfiles'] = {"BACKEND": "django.contrib.staticfiles.storage.ManifestStaticFilesStorage"}

# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
Expand All @@ -188,10 +201,6 @@
# dsn_configured_storage_class() requires the name of the setting
DefaultStorageClass = dsn_configured_storage_class('DEFAULT_STORAGE_DSN')

# Django's DEFAULT_FILE_STORAGE requires the class name
# To upload your media files to S3 set
DEFAULT_FILE_STORAGE = 'conf.settings.common.DefaultStorageClass'

MEDIA_URL = 'media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'data/media/')

Expand Down
5 changes: 3 additions & 2 deletions conf/settings/local.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
from .common import *

from .common import * # noqa


# Password validation
Expand All @@ -10,4 +11,4 @@
# Email settings

EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
EMAIL_FILE_PATH = os.path.join(BASE_DIR, 'tmp/mailbox')
EMAIL_FILE_PATH = os.path.join(BASE_DIR, 'tmp/mailbox') # noqa
8 changes: 4 additions & 4 deletions conf/settings/production.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from .common import *
from .common import * # noqa


# Email settings

EMAIL_BACKEND = 'anymail.backends.amazon_ses.EmailBackend'
ANYMAIL = {
'AMAZON_SES_CLIENT_PARAMS': {
'aws_access_key_id': env.str('AWS_ACCESS_KEY_SES', ''),
'aws_secret_access_key': env.str('AWS_SECRET_KEY_SES', ''),
'region_name': env.str('AWS_REGION_NAME_SES', ''),
'aws_access_key_id': env.str('AWS_ACCESS_KEY_SES', ''), # noqa
'aws_secret_access_key': env.str('AWS_SECRET_KEY_SES', ''), # noqa
'region_name': env.str('AWS_REGION_NAME_SES', ''), # noqa
}
}
6 changes: 3 additions & 3 deletions conf/settings/test.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import os
from .common import *
from .common import * # noqa

# Storages

MEDIA_ROOT = os.path.join(BASE_DIR, 'tmp/media')
MEDIA_ROOT = os.path.join(BASE_DIR, 'tmp/media') # noqa


# Email settings

EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
EMAIL_FILE_PATH = os.path.join(BASE_DIR, 'tmp/mailbox')
EMAIL_FILE_PATH = os.path.join(BASE_DIR, 'tmp/mailbox') # noqa
10 changes: 6 additions & 4 deletions conf/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,12 @@ def api_root(request):
# API
path('', api_root),
path('api/v1/', include((apps_patterns, 'v1'), namespace='v1')),
path('api/docs/', login_required(TemplateView.as_view(
template_name='docs/swagger-ui.html',
extra_context={'schema_url': 'openapi-schema'}
)), name='swagger-ui'),
path('api/docs/', login_required(
TemplateView.as_view(
template_name='docs/swagger-ui.html',
extra_context={'schema_url': 'openapi-schema'}
)
), name='swagger-ui'),

# Testing
path('sentry-debug/', trigger_error),
Expand Down
Loading

0 comments on commit bfde916

Please sign in to comment.