Browse Source

initial

master
Lucas 12 months ago
commit
c602d0bf8d
  1. 11
      .gitignore
  2. 26
      LICENSE
  3. 40
      Makefile
  4. 53
      README.md
  5. 122
      contrib/scripts/make_scripts.sh
  6. 0
      form_user/__init__.py
  7. 0
      form_user/apps/__init__.py
  8. 0
      form_user/apps/contas/__init__.py
  9. 64
      form_user/apps/contas/admin.py
  10. 7
      form_user/apps/contas/apps.py
  11. 28
      form_user/apps/contas/forms.py
  12. 33
      form_user/apps/contas/management/commands/elements.py
  13. 7
      form_user/apps/contas/managers.py
  14. 214
      form_user/apps/contas/migrations/0001_initial.py
  15. 27
      form_user/apps/contas/migrations/0002_alter_customuser_usuario_agrupador.py
  16. 0
      form_user/apps/contas/migrations/__init__.py
  17. 79
      form_user/apps/contas/models.py
  18. 15
      form_user/apps/contas/static/contas/css/main.css
  19. 13
      form_user/apps/contas/templates/contas/base.html
  20. 13
      form_user/apps/contas/templates/contas/form.html
  21. 13
      form_user/apps/contas/templates/contas/index.html
  22. 3
      form_user/apps/contas/tests.py
  23. 11
      form_user/apps/contas/urls.py
  24. 55
      form_user/apps/contas/views.py
  25. 16
      form_user/asgi.py
  26. 138
      form_user/settings.py
  27. 24
      form_user/urls.py
  28. 16
      form_user/wsgi.py
  29. 22
      manage.py
  30. 118
      poetry.lock
  31. 17
      pyproject.toml
  32. 8
      requirements.txt

11
.gitignore

@ -0,0 +1,11 @@
venv
.venv
.env
*.sqlite3
media
*__pycache__
.idea
*.code-workspace
.report.json
report.json
.vscode

26
LICENSE

@ -0,0 +1,26 @@
Copyright (c) Lucas F. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

40
Makefile

@ -0,0 +1,40 @@
.DEFAULT_GOAL = default
SCRIPT = contrib/scripts/make_scripts.sh
## @ env
.PHONY: env
env: ## creates a .env file
@./${SCRIPT} make_env_file
## @ task
.PHONY: check run shell_plus clear_migrations show_migrations migrations migrate elements
check: ## same as manage.py check
@./${SCRIPT} check
run: ## same as manage.py run server
@./${SCRIPT} run
shell_plus: ## same as .manage.py shell_plus
@./${SCRIPT} shell_plus
clear_migrations: ## same as manage.py showmigrations
@./${SCRIPT} show_migrations
show_migrations: ## same as manage.py showmigrations
@./${SCRIPT} show_migrations
migrations: ## same as manage.py makemigrations
@./${SCRIPT} migrations
migrate: ## same as manage.py migrate
@./${SCRIPT} migrate
elements: ## create initial app elements
@./${SCRIPT} elements
## @ help
.PHONY: help
help: ## display all make commands
@./${SCRIPT} help $(MAKEFILE_LIST)
default: help

53
README.md

@ -0,0 +1,53 @@
# Form User
É um exemplo de aplicação Django para criação de modelo, tendo em vista salvar dois modelos ao mesmo tempo,
sendo que um deles possui relação do tipo muitos para muitos.
## Instalação
via `pip`
```bash
git clone https://git.lucasf.dev/public/form_user.git
cd form_user
python -m venv .venv
. ./.venv/bin/activate
pip install -r requirements.txt
```
via `poetry`
```bash
git clone https://git.lucasf.dev/public/form_user.git
cd form_user
poetry shell
poetry install
```
## Criando arquivo .env
```bash
make env
```
## Criando elementos para aplicação
primeiro informe no arquivo `.env` gerado os valores para as seguintes variáveis:
ADMIN_USERNAME
ADMIN_EMAIL
ADMIN_PASSWORD
```bash
make elements
```
## Iniciar a aplicação
```bash
make run
```

122
contrib/scripts/make_scripts.sh

@ -0,0 +1,122 @@
#!/usr/bin/env bash
HERE="$(cd "$(dirname "$0")" && pwd)"
BASEDIR="$(cd "$(dirname "$1")" && pwd)"
CHARS="abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)"
for ((i=0;i<${#CHARS};i++)); do ARRAY[$i]="${CHARS:i:1}"; done
MSG_SUCCESS="DONE!"
POETRY=0
PYTHON=0
key_gen() {
for ((c=1; c<=50; c++)); do
KEY="$KEY${ARRAY[$((RANDOM % 50))]}"
done
echo $KEY
}
make_env_file() {
if [[ ! -f ".env" ]]; then
ENV="SECRET_KEY='$(key_gen)'\n
ALLOWED_HOSTS=localhost, 10.0.2.2, 127.0.0.1\n
DEBUG=True\n\n
#DATABASE_URL=postgres://postgres:postgres@127.0.0.1:5433/db\n\n
ADMIN_USERNAME=\n
ADMIN_EMAIL=\n
ADMIN_PASSWORD=\n\n
EMAIL_HOST=\n
EMAIL_PORT=\n
EMAIL_HOST_USER=\n
EMAIL_HOST_PASSWORD=\n
EMAIL_USE_TLS=True\n
DEFAULT_FROM_EMAIL=
"
$(echo -e $ENV | sed -e 's/^[ \t]*//' > .env)
echo "ENV FILE - $MSG_SUCCESS"
fi
}
verify_poetry() {
if command -v poetry &> /dev/null; then
POETRY=1
fi
}
verify_python() {
if command -v python3 &> /dev/null; then
PYTHON=1
fi
}
venv_name() {
if [[ -d "$BASEDIR/.venv" ]]; then
echo ".venv"
fi
if [[ -d "$BASEDIR/venv" ]]; then
echo "venv"
fi
}
python_name() {
if [[ PYTHON -eq 1 ]]; then
echo "python3"
else
echo "python"
fi
}
help() {
awk 'BEGIN {FS="## @ "; print "Usage: make";} /^## @ / { printf "\033[31m\n" substr($1, 5) "\n";} {FS=" ## ";} /^[a-zA-Z_-]+:.*? ##/ { print "\033[33m -", $1 "\033[37m", $2}' $ARG
}
run() {
$(venv_name)/bin/$(python_name) manage.py runserver 0.0.0.0:8000
}
shell_plus() {
$(venv_name)/bin/$(python_name) manage.py shell_plus
}
check() {
$(venv_name)/bin/$(python_name) manage.py check
IS_OK=$?
}
show_migrations() {
$(venv_name)/bin/$(python_name) manage.py showmigrations
}
migrations() {
$(venv_name)/bin/$(python_name) manage.py makemigrations
}
migrate() {
$(venv_name)/bin/$(python_name) manage.py migrate
}
check() {
$(venv_name)/bin/$(python_name) manage.py check
}
elements() {
$(venv_name)/bin/$(python_name) manage.py elements
}
clear_migrations() {
find $BASEDIR -path '*/migrations/*.py' -not -name '__init__.py' -not -path '*/.venv/*' -delete
find $BASEDIR -path '*/migrations/*.pyc' -not -name '__init__.py' -not -path '*/.venv/*' -delete
if [[ -f $BASEDIR/media/ ]]; then
rm $BASEDIR/media/*
fi
if [[ -f db.sqlite3 ]];then
rm db.sqlite3
fi
podman pod rm -f cq_pod &&
podman volume prune
}
verify_python
verify_poetry
ARG=$2
$1

0
form_user/__init__.py

0
form_user/apps/__init__.py

0
form_user/apps/contas/__init__.py

64
form_user/apps/contas/admin.py

@ -0,0 +1,64 @@
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.forms import UserCreationForm
from .forms import UserAdminForm
from .models import CustomUser, TagUnidade, Unidade, UsuarioPermissaoUnidadeTag
class UserAdmin(BaseUserAdmin):
add_form = UserCreationForm
add_fieldsets = (
(
None,
{
"classes": ("wide",),
"fields": (
"username",
"email",
"password1",
"password2",
"is_active",
),
},
),
)
form = UserAdminForm
fieldsets = (
(None, {"fields": ("username", "email")}),
(
"Informações Básicas",
{
"fields": (
"first_name",
"last_login",
)
},
),
(
"Permissões",
{
"fields": (
"is_active",
"is_staff",
"is_superuser",
"groups",
"user_permissions",
)
},
),
)
list_display = [
"username",
"first_name",
"email",
"is_active",
"is_staff",
"date_joined",
]
admin.site.register(CustomUser, UserAdmin)
admin.site.register(UsuarioPermissaoUnidadeTag)
admin.site.register(TagUnidade)
admin.site.register(Unidade)

7
form_user/apps/contas/apps.py

@ -0,0 +1,7 @@
from django.apps import AppConfig
class ContasConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "contas"
default = False

28
form_user/apps/contas/forms.py

@ -0,0 +1,28 @@
from django import forms
from django.contrib.auth.forms import UserCreationForm
from form_user.apps.contas.models import CustomUser, UsuarioPermissaoUnidadeTag
class UserAdminForm(forms.ModelForm):
class Meta:
model = CustomUser
fields = UserCreationForm.Meta.fields + (
"username",
"email",
"first_name",
"is_active",
"is_staff",
)
class PermissaoForm(forms.ModelForm):
class Meta:
model = UsuarioPermissaoUnidadeTag
fields = ["tags", "unidades"]
class NewUserForm(forms.ModelForm):
class Meta:
model = CustomUser
fields = ["username"]

33
form_user/apps/contas/management/commands/elements.py

@ -0,0 +1,33 @@
from decouple import config
from django.core.management.base import BaseCommand
from django.utils.translation import gettext_lazy as _
from form_user.apps.contas.models import CustomUser
class AppException(Exception, BaseCommand):
def __init__(self, exception):
print(
BaseCommand().stdout.write(
BaseCommand().style.NOTICE(f"Error: {exception}")
)
)
class Command(BaseCommand):
help = _("Creates initial information for application")
su_created = False
def handle(self, *args, **options):
if not CustomUser.objects.filter(username=config("ADMIN_USERNAME")):
su = CustomUser.objects.create_superuser(
username=config("ADMIN_USERNAME"),
email=config("ADMIN_EMAIL"),
password=config("ADMIN_PASSWORD"),
is_active=True,
is_staff=True,
)
if su:
self.stdout.write(self.style.SUCCESS(_("Superuser created!")))
else:
self.stdout.write(self.style.NOTICE(_("Superuser already exists!")))

7
form_user/apps/contas/managers.py

@ -0,0 +1,7 @@
from django.contrib.auth.models import UserManager
from django.db.models import Q
class CustomUserManager(UserManager):
def all(self):
return self.get_queryset().filter(~Q(username="admin"))

214
form_user/apps/contas/migrations/0001_initial.py

@ -0,0 +1,214 @@
# Generated by Django 5.0.2 on 2024-02-06 18:32
import django.contrib.auth.validators
import django.db.models.deletion
import django.utils.timezone
import form_user.apps.contas.managers
import uuid
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
("auth", "0012_alter_user_first_name_max_length"),
]
operations = [
migrations.CreateModel(
name="TagUnidade",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("nome", models.CharField(max_length=50, verbose_name="Nome")),
],
),
migrations.CreateModel(
name="Unidade",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("nome", models.CharField(max_length=50, verbose_name="Nome")),
],
),
migrations.CreateModel(
name="CustomUser",
fields=[
("password", models.CharField(max_length=128, verbose_name="password")),
(
"last_login",
models.DateTimeField(
blank=True, null=True, verbose_name="last login"
),
),
(
"is_superuser",
models.BooleanField(
default=False,
help_text="Designates that this user has all permissions without explicitly assigning them.",
verbose_name="superuser status",
),
),
(
"username",
models.CharField(
error_messages={
"unique": "A user with that username already exists."
},
help_text="Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.",
max_length=150,
unique=True,
validators=[
django.contrib.auth.validators.UnicodeUsernameValidator()
],
verbose_name="username",
),
),
(
"first_name",
models.CharField(
blank=True, max_length=150, verbose_name="first name"
),
),
(
"last_name",
models.CharField(
blank=True, max_length=150, verbose_name="last name"
),
),
(
"email",
models.EmailField(
blank=True, max_length=254, verbose_name="email address"
),
),
(
"date_joined",
models.DateTimeField(
default=django.utils.timezone.now, verbose_name="date joined"
),
),
(
"id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
verbose_name="Identifier",
),
),
(
"is_staff",
models.BooleanField(default=False, verbose_name="staff status"),
),
(
"is_active",
models.BooleanField(default=False, verbose_name="active"),
),
(
"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",
),
),
(
"usuario_agrupador",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="agrupador",
to=settings.AUTH_USER_MODEL,
verbose_name="Usuário Agrupador",
),
),
],
options={
"verbose_name": "Usuário",
"verbose_name_plural": "Usuários",
},
managers=[
("objects", form_user.apps.contas.managers.CustomUserManager()),
],
),
migrations.CreateModel(
name="UsuarioPermissaoUnidadeTag",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"tags",
models.ManyToManyField(to="contas.tagunidade", verbose_name="Tags"),
),
(
"unidades",
models.ManyToManyField(
to="contas.unidade", verbose_name="Unidades"
),
),
(
"usuario",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="per_custom_user",
to=settings.AUTH_USER_MODEL,
),
),
(
"usuario_inclusao",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="usuario_inclusao",
to=settings.AUTH_USER_MODEL,
),
),
],
options={
"verbose_name": "PermissĂŁo de Acesso Tag e Unidade",
"verbose_name_plural": "Permissões de Acesso Tags e Unidades",
},
),
]

27
form_user/apps/contas/migrations/0002_alter_customuser_usuario_agrupador.py

@ -0,0 +1,27 @@
# Generated by Django 5.0.2 on 2024-02-06 18:35
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("contas", "0001_initial"),
]
operations = [
migrations.AlterField(
model_name="customuser",
name="usuario_agrupador",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="agrupador",
to=settings.AUTH_USER_MODEL,
verbose_name="Usuário Agrupador",
),
),
]

0
form_user/apps/contas/migrations/__init__.py

79
form_user/apps/contas/models.py

@ -0,0 +1,79 @@
import uuid
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.utils.translation import gettext_lazy as _
from .managers import CustomUserManager
class TagUnidade(models.Model):
nome = models.CharField("Nome", max_length=50)
def __str__(self):
return self.nome
class Unidade(models.Model):
nome = models.CharField("Nome", max_length=50)
def __str__(self):
return self.nome
class CustomUser(AbstractUser):
id = models.UUIDField(
_("Identifier"), primary_key=True, default=uuid.uuid4, editable=False
)
is_staff = models.BooleanField(_("staff status"), default=False)
is_active = models.BooleanField(_("active"), default=False)
usuario_agrupador = models.ForeignKey(
"self",
on_delete=models.CASCADE,
verbose_name="Usuário Agrupador",
related_name="agrupador",
null=True,
blank=True,
)
EMAIL_FIELD = "email"
USERNAME_FIELD = "username"
REQUIRED_FIELDS = ["email"]
objects = CustomUserManager()
class Meta:
verbose_name = "Usuário"
verbose_name_plural = "Usuários"
def __str__(self):
return self.first_name or self.username
class UsuarioPermissaoUnidadeTag(models.Model):
usuario = models.ForeignKey(
CustomUser,
on_delete=models.CASCADE,
related_name="per_custom_user",
null=True,
blank=True,
)
tags = models.ManyToManyField(TagUnidade, verbose_name="Tags")
unidades = models.ManyToManyField(Unidade, verbose_name="Unidades")
usuario_inclusao = models.ForeignKey(
CustomUser,
on_delete=models.CASCADE,
related_name="usuario_inclusao",
null=True,
blank=True,
)
def __str__(self):
return self.usuario.username
class Meta:
verbose_name = "PermissĂŁo de Acesso Tag e Unidade"
verbose_name_plural = "Permissões de Acesso Tags e Unidades"

15
form_user/apps/contas/static/contas/css/main.css

@ -0,0 +1,15 @@
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
display: grid;
place-content: center;
align-items: center;
height: 100vh;
}

13
form_user/apps/contas/templates/contas/base.html

@ -0,0 +1,13 @@
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="{% static 'contas/css/main.css' %}">
<title>Form Test</title>
</head>
<body>
{% block content %}{% endblock content %}
</body>
</html>

13
form_user/apps/contas/templates/contas/form.html

@ -0,0 +1,13 @@
{% extends "contas/base.html" %}
{% load static %}
{% block content %}
<a href="{% url 'contas:index' %}">Voltar</a>
<form action="" method="post" style="margin-top: 2rem;" autocomplete="off">
{% csrf_token %}
{{ form.as_p }}
{{ form_permissao.as_p }}
<input type="submit" value="Salvar">
</form>
{% endblock content %}

13
form_user/apps/contas/templates/contas/index.html

@ -0,0 +1,13 @@
{% extends "contas/base.html" %}
{% load static %}
{% block content %}
<a href="{% url 'contas:novo' %}">Novo Usuário</a><br>
<ul style="margin-top: 2rem;">
{% for object in object_list %}
<li><a href="{% url 'contas:editar' object.pk %}">{{object}}</a></li>
{% endfor %}
</ul>
{% endblock content %}

3
form_user/apps/contas/tests.py

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

11
form_user/apps/contas/urls.py

@ -0,0 +1,11 @@
from django.urls import path
from . import views
app_name = "contas"
urlpatterns = [
path("", views.Index.as_view(), name="index"),
path("novo/", views.Novo.as_view(), name="novo"),
path("editar/<uuid:pk>/", views.Editar.as_view(), name="editar"),
]

55
form_user/apps/contas/views.py

@ -0,0 +1,55 @@
from django.db import transaction
from django.http import HttpResponseRedirect
from django.urls import reverse_lazy
from django.views.generic import CreateView, ListView, UpdateView
from form_user.apps.contas.models import CustomUser
from . import forms
class Common:
model = CustomUser
template_name = "contas/form.html"
form_class = forms.NewUserForm
success_url = reverse_lazy("contas:index")
class Index(Common, ListView):
template_name = "contas/index.html"
paginate_by = 10
class NovoEditar(Common):
def form_valid(self, form):
form_permissao = forms.PermissaoForm(self.request.POST)
form_permissao.full_clean()
if not form_permissao.is_valid():
context = self.get_context_data(form=form)
context.update(form_permissao=form_permissao)
return self.render_to_response(context)
with transaction.atomic():
ob = form.save()
form_permissao.instance.usuario = ob
form_permissao.instance.usuario_inclusao = ob
form_permissao.save()
return HttpResponseRedirect(self.success_url)
class Novo(NovoEditar, CreateView):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["form_permissao"] = forms.PermissaoForm()
return context
class Editar(NovoEditar, UpdateView):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["form_permissao"] = forms.PermissaoForm(
instance=self.object.per_custom_user.first()
)
return context

16
form_user/asgi.py

@ -0,0 +1,16 @@
"""
ASGI config for form_user project.
It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/
"""
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'form_user.settings')
application = get_asgi_application()

138
form_user/settings.py

@ -0,0 +1,138 @@
"""
Django settings for form_user project.
Generated by 'django-admin startproject' using Django 5.0.2.
For more information on this file, see
https://docs.djangoproject.com/en/5.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/5.0/ref/settings/
"""
import os
from pathlib import Path
from decouple import Csv, config
from dj_database_url import parse as dburl
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = config("SECRET_KEY")
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = config("DEBUG", default=False, cast=bool)
ALLOWED_HOSTS = config("ALLOWED_HOSTS", cast=Csv())
# Application definition
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"django_extensions",
"form_user.apps.contas",
]
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",
]
ROOT_URLCONF = "form_user.urls"
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": ["templates", BASE_DIR / "templates"],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]
WSGI_APPLICATION = "form_user.wsgi.application"
# Database
# https://docs.djangoproject.com/en/5.0/ref/settings/#databases
default_dburl = "sqlite:///" + os.path.join(BASE_DIR, "db.sqlite3")
DATABASES = {
"default": config("DATABASE_URL", default=default_dburl, cast=dburl),
}
# Password validation
# https://docs.djangoproject.com/en/5.0/ref/settings/#auth-password-validators
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",
},
]
# Internationalization
# https://docs.djangoproject.com/en/5.0/topics/i18n/
LANGUAGE_CODE = "en-us"
TIME_ZONE = "UTC"
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.0/howto/static-files/
STATIC_URL = "static/"
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "staticfiles"),
]
MEDIA_URL = "/media/"
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
# Default primary key field type
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
AUTH_USER_MODEL = "contas.CustomUser"

24
form_user/urls.py

@ -0,0 +1,24 @@
"""
URL configuration for form_user project.
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/5.0/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path("admin/", admin.site.urls),
path("", include("form_user.apps.contas.urls", namespace="contas")),
]

16
form_user/wsgi.py

@ -0,0 +1,16 @@
"""
WSGI config for form_user project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'form_user.settings')
application = get_wsgi_application()

22
manage.py

@ -0,0 +1,22 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'form_user.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()

118
poetry.lock

@ -0,0 +1,118 @@
# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
[[package]]
name = "asgiref"
version = "3.7.2"
description = "ASGI specs, helper code, and adapters"
optional = false
python-versions = ">=3.7"
files = [
{file = "asgiref-3.7.2-py3-none-any.whl", hash = "sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e"},
{file = "asgiref-3.7.2.tar.gz", hash = "sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed"},
]
[package.extras]
tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"]
[[package]]
name = "dj-database-url"
version = "2.1.0"
description = "Use Database URLs in your Django Application."
optional = false
python-versions = "*"
files = [
{file = "dj-database-url-2.1.0.tar.gz", hash = "sha256:f2042cefe1086e539c9da39fad5ad7f61173bf79665e69bf7e4de55fa88b135f"},
{file = "dj_database_url-2.1.0-py3-none-any.whl", hash = "sha256:04bc34b248d4c21aaa13e4ab419ae6575ef5f10f3df735ce7da97722caa356e0"},
]
[package.dependencies]
Django = ">=3.2"
typing-extensions = ">=3.10.0.0"
[[package]]
name = "django"
version = "5.0.2"
description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design."
optional = false
python-versions = ">=3.10"
files = [
{file = "Django-5.0.2-py3-none-any.whl", hash = "sha256:56ab63a105e8bb06ee67381d7b65fe6774f057e41a8bab06c8020c8882d8ecd4"},
{file = "Django-5.0.2.tar.gz", hash = "sha256:b5bb1d11b2518a5f91372a282f24662f58f66749666b0a286ab057029f728080"},
]
[package.dependencies]
asgiref = ">=3.7.0,<4"
sqlparse = ">=0.3.1"
tzdata = {version = "*", markers = "sys_platform == \"win32\""}
[package.extras]
argon2 = ["argon2-cffi (>=19.1.0)"]
bcrypt = ["bcrypt"]
[[package]]
name = "django-extensions"
version = "3.2.3"
description = "Extensions for Django"
optional = false
python-versions = ">=3.6"
files = [
{file = "django-extensions-3.2.3.tar.gz", hash = "sha256:44d27919d04e23b3f40231c4ab7af4e61ce832ef46d610cc650d53e68328410a"},
{file = "django_extensions-3.2.3-py3-none-any.whl", hash = "sha256:9600b7562f79a92cbf1fde6403c04fee314608fefbb595502e34383ae8203401"},
]
[package.dependencies]
Django = ">=3.2"
[[package]]
name = "python-decouple"
version = "3.8"
description = "Strict separation of settings from code."
optional = false
python-versions = "*"
files = [
{file = "python-decouple-3.8.tar.gz", hash = "sha256:ba6e2657d4f376ecc46f77a3a615e058d93ba5e465c01bbe57289bfb7cce680f"},
{file = "python_decouple-3.8-py3-none-any.whl", hash = "sha256:d0d45340815b25f4de59c974b855bb38d03151d81b037d9e3f463b0c9f8cbd66"},
]
[[package]]
name = "sqlparse"
version = "0.4.4"
description = "A non-validating SQL parser."
optional = false
python-versions = ">=3.5"
files = [
{file = "sqlparse-0.4.4-py3-none-any.whl", hash = "sha256:5430a4fe2ac7d0f93e66f1efc6e1338a41884b7ddf2a350cedd20ccc4d9d28f3"},
{file = "sqlparse-0.4.4.tar.gz", hash = "sha256:d446183e84b8349fa3061f0fe7f06ca94ba65b426946ffebe6e3e8295332420c"},
]
[package.extras]
dev = ["build", "flake8"]
doc = ["sphinx"]
test = ["pytest", "pytest-cov"]
[[package]]
name = "typing-extensions"
version = "4.9.0"
description = "Backported and Experimental Type Hints for Python 3.8+"
optional = false
python-versions = ">=3.8"
files = [
{file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"},
{file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"},
]
[[package]]
name = "tzdata"
version = "2023.4"
description = "Provider of IANA time zone data"
optional = false
python-versions = ">=2"
files = [
{file = "tzdata-2023.4-py2.py3-none-any.whl", hash = "sha256:aa3ace4329eeacda5b7beb7ea08ece826c28d761cda36e747cfbf97996d39bf3"},
{file = "tzdata-2023.4.tar.gz", hash = "sha256:dd54c94f294765522c77399649b4fefd95522479a664a0cec87f41bebc6148c9"},
]
[metadata]
lock-version = "2.0"
python-versions = "^3.11"
content-hash = "3f3d4eb61266813806f194403d47bbd1801f62ca247a7ef3dc226a606fe9327f"

17
pyproject.toml

@ -0,0 +1,17 @@
[tool.poetry]
name = "form-user"
version = "0.1.0"
description = ""
authors = ["Lucas F. <lucas@lucasf.dev>"]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.11"
django = "^5.0.2"
python-decouple = "^3.8"
django-extensions = "^3.2.3"
dj-database-url = "^2.1.0"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

8
requirements.txt

@ -0,0 +1,8 @@
asgiref==3.7.2 ; python_version >= "3.11" and python_version < "4.0"
dj-database-url==2.1.0 ; python_version >= "3.11" and python_version < "4.0"
django-extensions==3.2.3 ; python_version >= "3.11" and python_version < "4.0"
django==5.0.2 ; python_version >= "3.11" and python_version < "4.0"
python-decouple==3.8 ; python_version >= "3.11" and python_version < "4.0"
sqlparse==0.4.4 ; python_version >= "3.11" and python_version < "4.0"
typing-extensions==4.9.0 ; python_version >= "3.11" and python_version < "4.0"
tzdata==2023.4 ; python_version >= "3.11" and python_version < "4.0" and sys_platform == "win32"
Loading…
Cancel
Save