


Arquivo de configurações gerais do projeto.
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
SECRET_KEY = 'CHAVES' # Não seguro. Ideal informar a chave em variáveis de ambiente (arquivo .env) e referenciar aqui usando os.environ.get('SECRET_KEY')
DEBUG = True # True para projeto em desenvolvimento, False para produção
ALLOWED_HOSTS = [] # Lista de IPs ou domínios permitidos para acessar a aplicação
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'corsheaders',
'nomeAppDoProjeto',
] # Lista de apps instalados no projeto, incluindo apps personalizados e de terceiros
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'corsheaders.middleware.CorsMiddleware',
] # Lista de middlewares usados no projeto, incluindo middlewares de segurança, autenticação e CORS
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
#'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticatedOrReadOnly',
),
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 2,
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle',
),
'DEFAULT_THROTTLE_RATES': {
'anon': '2/minute', #second,day,month,year
'user': '3/minute'
},
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
],
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
]
} # Configurações do Django REST Framework para usar JSON como formato de entrada e saída, autenticação por token, permissões de leitura para não autenticados e paginação de resultados
CORS_ALLOW_ALL_ORIGINS = True # Permite que qualquer origem acesse API. Em produção, recomenda-se configurar CORS de forma mais restritiva usando CORS_ALLOWED_ORIGINS
ROOT_URLCONF = 'paris_cafe.urls' # Módulo de URLs raiz do projeto, onde rotas principais são definidas
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
] # Configurações de templates do Django, incluindo diretórios de templates e processadores de contexto
WSGI_APPLICATION = 'paris_cafe.wsgi.application' # Módulo WSGI do projeto, usado para implantação em servidores compatíveis com WSGI
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
} # Configurações de banco de dados, usando SQLite para desenvolvimento
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
] # Configurações de validação de senha para garantir senhas seguras
# Configurações de internacionalização e fuso horário:
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True
STATIC_URL = 'static/' # URL para servir arquivos estáticos (CSS, JavaScript, imagens)
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' # Configuração para usar BigAutoField como tipo de campo padrão para chaves primárias em modelos, garantindo IDs únicos e escaláveis
MEDIA_URL = '/media/' # URL para servir arquivos de mídia enviados pelos usuários
MEDIA_ROOT = os.path.join(BASE_DIR, 'media') # Diretório onde arquivos de mídia serão armazenados no sistema de arquivos do servidor
LOGIN_URL = '/login' # URL para página de login, onde usuários não autenticados serão redirecionados ao tentar acessar áreas protegidas do site
LOGIN_REDIRECT_URL = '/'
LOGOUT_URL = '/logout'
LOGOUT_REDIRECT_URL = '/login'
AUTHENTICATION_BACKENDS = [
'social_core.backends.google.GoogleOAuth2',
'social_core.backends.facebook.FacebookOAuth2',
'django.contrib.auth.backends.ModelBackend',
]
SOCIAL_AUTH_FACEBOOK_EXTRA_DATA = [
('name', 'name'),
('email', 'email'),
('picture', 'picture'),
('link', 'profile_url'),
]
import django_heroku
django_heroku.settings(locals())
Arquivo contendo Models da aplicação. Pode estar localizado em diretório chamado, models dentra da pasta da app, onde cada Model é arquivo cujo nome é mesmo da respectiva classe. Models são classes de persistência, responsável por representar tabela do banco de dados e seus campos. Cada atributo da classe representa campo da tabela (com suas características e condições), onde Django se encarrega de criar estrutura do banco de dados com base nessas definições. Models também podem incluir métodos para manipulação dos dados, como validação, formatação ou cálculos relacionados aos campos definidos. Exemplo de model (models/activity.py):
from django.db import models
class Activity(models.Model):
strava_id = models.BigIntegerField(
unique=True,
help_text="ID da atividade no Strava",
)
name = models.CharField(
max_length=255,
help_text="Nome da atividade",
)
distance = models.FloatField(
help_text="Distância em metros",
)
moving_time = models.PositiveIntegerField(
help_text="Tempo em movimento (segundos)",
)
sport_type = models.CharField(
max_length=50,
help_text="Tipo de esporte (Run, Walk, Ride, etc)",
)
start_date = models.DateTimeField(
help_text="Data/hora de início (UTC)",
)
average_speed = models.FloatField(
null=True,
blank=True,
help_text="Velocidade média (m/s)",
)
created_at = models.DateTimeField(
auto_now_add=True,
)
class Meta:
ordering = ["-start_date"]
verbose_name = "Atividade"
verbose_name_plural = "Atividades"
def __str__(self) -> str:
return f"{self.name} - {self.distance / 1000:.2f} km"
Exemplo de Model com métodos (models/Profile.py):
from medicSearch.models import *
from django.db.models import Sum, Count
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
role = models.IntegerField(choices=ROLE_CHOICE, default=3)
birthday = models.DateField(default=None, null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
token = models.CharField(max_length=255, null=True, blank=True)
image = models.ImageField(null=True, blank=True)
favorites = models.ManyToManyField(User, blank=True, related_name='favorites')
specialties = models.ManyToManyField(Speciality, blank=True, related_name='specialties')
addresses = models.ManyToManyField(Address, blank=True, related_name='addresses')
def __str__(self):
return '{}'.format(self.user.username)
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
try:
if created:
Profile.objects.create(user=instance)
except:
pass
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
try:
instance.profile.save()
except:
pass
def show_scoring_average(self):
from .Rating import Rating
try:
ratings = Rating.objects.filter(user_rated=self.user).aggregate(Sum('value'), Count('user'))
if ratings['user__count'] > 0:
scoring_average = ratings['value__sum'] / ratings['user__count']
scoring_average = round(scoring_average, 2) # Arredondando o valor para duas casas decimais
return scoring_average
return 'Sem avaliações'
except:
return 'Sem avaliações'
def show_favorites(self):
ids = [result.id for result in self.favorites.all()]
return Profile.objects.filter(user__id__in=ids)
def show_ratings(self):
from .Rating import Rating
return Rating.objects.filter(user_rated=self.user)
Exemplo de Model com Meta (models/Profile.py):
from django.db import models
class Base(models.Model):
criacao = models.DateTimeField(auto_now_add=True)
atualizacao = models.DateTimeField(auto_now=True)
ativo = models.BooleanField(default=True)
class Meta:
abstract = True
class Curso(Base):
titulo = models.CharField(max_length=255)
url = models.URLField(unique=True)
class Meta:
verbose_name = 'Curso'
verbose_name_plural = 'Cursos'
ordering = ['id']
#Decrescente: ordering = ['-id']
def __str__(self):
return self.titulo
class Avaliacao(Base):
curso = models.ForeignKey(Curso, related_name='avaliacoes', on_delete=models.CASCADE)
nome = models.CharField(max_length=255)
email = models.EmailField()
comentario = models.TextField(blank=True, default='')
avaliacao = models.DecimalField(max_digits=2, decimal_places=1)
class Meta:
verbose_name = 'Avaliação'
verbose_name_plural = 'Avaliações'
unique_together = ['email', 'curso']
ordering = ['id']
def __str__(self):
return f'{self.nome} avaliou o curso {self.curso} com nota {self.avaliacao}'
Opcionalmente, alguns projetos possui models na pasta de models, onde há arquivo de inicialização e regras de negócio (__init__.py):
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
ROLE_CHOICE = (
(1, 'Admin'),
(2, 'Médico'),
(3, 'Paciente')
)
# Outras models desse projeto específico:
from .Rating import Rating
from .DayWeek import DayWeek
from .State import State
from .City import City
from .Neighborhood import Neighborhood
from .Address import Address
from .Speciality import Speciality
from .Profile import Profile
Arquivo de rotas globais do projeto, onde são mapeadas URLs para respectivas views, acessíveis a todo projeto. Geralmente localizado em pastaProjeto/urls.py. Exemplo:
from django.contrib import admin
from django.urls import path
from django.conf.urls.static import static
from django.conf import settings
from django.conf.urls import url, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('medicSearch.urls.HomeUrls')),
path('', include('medicSearch.urls.AuthUrls')),
path('profile/', include('medicSearch.urls.ProfileUrls')),
path('medic/', include('medicSearch.urls.MedicUrls')),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Exemplo simples (pastaProjeto/urls.py):
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('cafes.urls')), # Arquivo de rotas locais, da app 'cafes'
]
Exemplo, usando versionamento de APIs REST (pastaProjeto/urls.py):
from django.contrib import admin
from django.urls import path, include
from cursos.urls import router
urlpatterns = [
path('api/v1/', include('cursos.urls')),
path('api/v2/', include(router.urls)),
path('admin/', admin.site.urls),
path('auth/', include('rest_framework.urls')),
]
Exemplo, usando ViewSets (pastaProjeto/urls.py):
from django.urls import path
from .views import BookListCreateView, BookRetrieveUpdateDestroyView
urlpatterns = [
path('books/', BookListCreateView.as_view(), name='book-list-create'),
path('books/<int:pk>/', BookRetrieveUpdateDestroyView.as_view(), name='book-detail'),
]
Exemplo, usando JWT (pastaProjeto/urls.py):
from django.contrib import admin
from django.urls import path, include
from rest_framework_simplejwt.views import (
TokenObtainPairView,
TokenRefreshView,
)
urlpatterns = [
path("admin/", admin.site.urls),
path("api/auth/token/", TokenObtainPairView.as_view(), name="token_obtain_pair"),
path("api/auth/token/refresh/", TokenRefreshView.as_view(), name="token_refresh"),
path("api/", include("apps.activities.urls")),
]
Em breve...
Elaborado por Mateus Schwede
ubsocial.github.io