Merge branch 'crispy-forms' into 'master'

Crispy forms

See merge request JustScreaMy/facturio!1
This commit is contained in:
Jakub Kropáček 2023-12-19 12:49:35 +00:00
commit 8bbfb6010c
21 changed files with 172 additions and 65 deletions

View file

@ -1,13 +1,29 @@
from crispy_forms import helper, layout
from django.contrib.auth.forms import AuthenticationForm, UserCreationForm
from .models import User
# from .models import User
class LoginForm(AuthenticationForm):
pass
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = helper.FormHelper()
self.helper.form_action = "login"
self.helper.form_method = "post"
self.helper.add_input(layout.Submit('submit', 'Login'))
#
# class RegisterForm(UserCreationForm):
# class Meta(UserCreationForm.Meta):
# model = User
# fields = UserCreationForm.Meta.fields
class RegisterForm(UserCreationForm):
class Meta:
model = User
fields = UserCreationForm.Meta.fields + ("first_name", "last_name", "email")
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = helper.FormHelper()
self.helper.form_action = "register"
self.helper.form_method = "post"
self.helper.add_input(layout.Submit('submit', 'Register'))

View file

@ -0,0 +1,27 @@
# Generated by Django 5.0 on 2023-12-19 11:53
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("account", "0001_initial"),
]
operations = [
migrations.AlterField(
model_name="user",
name="email",
field=models.EmailField(max_length=254, verbose_name="email address"),
),
migrations.AlterField(
model_name="user",
name="first_name",
field=models.CharField(max_length=150, verbose_name="first name"),
),
migrations.AlterField(
model_name="user",
name="last_name",
field=models.CharField(max_length=150, verbose_name="last name"),
),
]

View file

@ -1,5 +1,14 @@
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.utils.translation import gettext_lazy as _
class User(AbstractUser):
pass
REQUIRED_FIELDS = ["email", "first_name", "last_name"]
first_name = models.CharField(_("first name"), max_length=150)
last_name = models.CharField(_("last name"), max_length=150)
email = models.EmailField(_("email address"))
class Meta(AbstractUser.Meta):
pass

View file

@ -1,32 +1,9 @@
{% extends "facturio/base.html" %}
{% load crispy_forms_tags %}
{% block title %}Login{% endblock %}
{% block content %}
<div class="container mt-5">
<form class="col-md-6 offset-md-3" action="{% url 'login' %}" method="post">
{% csrf_token %}
<div class="mb-3">
<label for="username" class="form-label">Username</label>
<input type="text" class="form-control" name="username" id="username" required>
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input type="password" class="form-control" name="password" id="password" required>
</div>
<button type="submit" class="btn btn-primary">Login</button>
</form>
{# <form class="col-md-6 offset-md-3" action="{% url 'login' %}" method="post">#}
{# {% csrf_token %}#}
{# <div class="mb-3">#}
{# <label for="username" class="form-label">Username</label>#}
{# <input type="text" class="form-control" name="username" id="username" required>#}
{# </div>#}
{# <div class="mb-3">#}
{# <label for="password" class="form-label">Password</label>#}
{# <input type="password" class="form-control" name="password" id="password" required>#}
{# </div>#}
{# <button type="submit" class="btn btn-primary">Login</button>#}
{# </form>#}
</div>
{% crispy form form.helper %}
{% endblock %}

View file

@ -6,10 +6,11 @@
<div class="container mt-4">
<h2 class="mb-4">About Me</h2>
<div class="card">
<div class="card-body">
<h5 class="card-title">Welcome, {{ request.user.username }}!</h5>
<p class="card-text">Email: {{ request.user.email }}</p>
</div>
<h5 class="card-header">Welcome, {{ request.user.first_name }} {{ request.user.last_name }}!</h5>
<ul class="list-group list-group-flush">
<li class="list-group-item">Username: {{ request.user.username }}</li>
<li class="list-group-item">Email: {{ request.user.email }}</li>
</ul>
</div>
</div>
{% endblock %}

View file

@ -1,5 +1,10 @@
{% extends "facturio/base.html" %}
{% load crispy_forms_tags %}
{% block title %}Register{% endblock %}
{% block content %}
<h1>TODO: register</h1>
{# TODO: neukazovat všechny pičoviny hned najedou#}
{% crispy form form.helper %}
{% endblock %}

View file

@ -1,15 +1,15 @@
from django.conf import settings
from django.contrib.auth import login, logout
from django.contrib.auth.decorators import login_required
from django.http import HttpRequest, HttpResponse, JsonResponse
from django.shortcuts import redirect, render
from django.http import HttpRequest, HttpResponse
from django.shortcuts import redirect, render, reverse
from . import forms
def auth_login(req: HttpRequest) -> HttpResponse:
if req.method == "POST":
form = forms.LoginForm(req, req.POST)
form = forms.LoginForm(data=req.POST)
if not form.is_valid():
return render(req, "account/login.html", dict(form=form))
@ -21,8 +21,7 @@ def auth_login(req: HttpRequest) -> HttpResponse:
return redirect(redirect_url)
elif req.method == "GET":
form = forms.LoginForm(req)
form = forms.LoginForm()
return render(req, "account/login.html", dict(form=form))
return HttpResponse(status=405)
@ -35,7 +34,23 @@ def auth_logout(req: HttpRequest) -> HttpResponse:
def auth_register(req: HttpRequest) -> HttpResponse:
return render(req, "account/register.html")
if req.user.is_authenticated:
return redirect(reverse("me"))
if req.method == "POST":
form = forms.RegisterForm(data=req.POST)
if not form.is_valid():
return render(req, "account/register.html", dict(form=form))
user = form.save()
login(req, user)
return redirect(settings.LOGIN_BASE_URL)
elif req.method == "GET":
form = forms.RegisterForm()
return render(req, "account/register.html", dict(form=form))
return HttpResponse(status=405)
@login_required

View file

@ -35,7 +35,10 @@ INSTALLED_APPS = [
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"account.apps.AccountConfig"
"crispy_forms",
"crispy_bootstrap5",
"account.apps.AccountConfig",
"subjects.apps.SubjectsConfig"
]
MIDDLEWARE = [
@ -124,3 +127,8 @@ LOGOUT_REDIRECT_URL = f"/"
LOGIN_REDIRECT_URL = f"{LOGIN_BASE_URL}/me"
AUTH_USER_MODEL = "account.User"
# Crispy config
CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5"
CRISPY_TEMPLATE_PACK = "bootstrap5"

View file

@ -15,20 +15,17 @@ Including another URLconf
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
# TODO: remove
from django.http import HttpRequest, HttpResponse
from django.shortcuts import render
from django.urls import path, include
# TODO: remove
def demo(req: HttpRequest) -> HttpResponse:
return render(req, "facturio/invoice.html")
def landing_page(req: HttpRequest) -> HttpResponse:
return render(req, "facturio/index.html")
urlpatterns = [
path("", demo, name="main-page"),
path("", landing_page, name="main-page"),
path("account/", include("account.urls")),
path("admin/", admin.site.urls),
]

34
poetry.lock generated
View file

@ -14,6 +14,24 @@ files = [
[package.extras]
tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"]
[[package]]
name = "crispy-bootstrap5"
version = "2023.10"
description = "Bootstrap5 template pack for django-crispy-forms"
optional = false
python-versions = ">=3.8"
files = [
{file = "crispy-bootstrap5-2023.10.tar.gz", hash = "sha256:f16c44f1997310e5a89c0cf230402e7111cc1f942f64fb7e44603958b89b06a1"},
{file = "crispy_bootstrap5-2023.10-py3-none-any.whl", hash = "sha256:9b5a6c9880f37cd32aa678c0d7576ae60b3e502c444c8712e582f8bd91659afb"},
]
[package.dependencies]
django = ">=4.2"
django-crispy-forms = ">=2"
[package.extras]
test = ["pytest", "pytest-django"]
[[package]]
name = "django"
version = "5.0"
@ -34,6 +52,20 @@ tzdata = {version = "*", markers = "sys_platform == \"win32\""}
argon2 = ["argon2-cffi (>=19.1.0)"]
bcrypt = ["bcrypt"]
[[package]]
name = "django-crispy-forms"
version = "2.1"
description = "Best way to have Django DRY forms"
optional = false
python-versions = ">=3.8"
files = [
{file = "django-crispy-forms-2.1.tar.gz", hash = "sha256:4d7ec431933ad4d4b5c5a6de4a584d24613c347db9ac168723c9aaf63af4bb96"},
{file = "django_crispy_forms-2.1-py3-none-any.whl", hash = "sha256:d592044771412ae1bd539cc377203aa61d4eebe77fcbc07fbc8f12d3746d4f6b"},
]
[package.dependencies]
django = ">=4.2"
[[package]]
name = "sqlparse"
version = "0.4.4"
@ -64,4 +96,4 @@ files = [
[metadata]
lock-version = "2.0"
python-versions = "^3.12"
content-hash = "1c6ab57fc89858a0923620d3307e9173662bad9b58d9dde4f567267506e03587"
content-hash = "a3eaa3850f93a5b33da70f1d4831d68ee7593e05e7a0e040de0cc09229be92fd"

View file

@ -9,6 +9,8 @@ readme = "README.md"
[tool.poetry.dependencies]
python = "^3.12"
django = "^5.0"
crispy-bootstrap5 = "^2023.10"
django-crispy-forms = "^2.1"
[build-system]

0
subjects/__init__.py Normal file
View file

3
subjects/admin.py Normal file
View file

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

6
subjects/apps.py Normal file
View file

@ -0,0 +1,6 @@
from django.apps import AppConfig
class SubjectsConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "subjects"

View file

3
subjects/models.py Normal file
View file

@ -0,0 +1,3 @@
from django.db import models
# Create your models here.

3
subjects/tests.py Normal file
View file

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

3
subjects/views.py Normal file
View file

@ -0,0 +1,3 @@
# Create your views here.
ARES_BASE_URL = "https://wwwinfo.mfcr.cz/cgi-bin/ares/darv_rzp.cgi?ico=27074358&xml=0&ver=1.0.4"

View file

@ -9,26 +9,25 @@
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="#">Facturio</a>
<a class="navbar-brand" href="{% url "main-page" %}">Facturio</a>
<!-- Left-aligned items -->
<div class="collapse navbar-collapse" id="navbarLeft">
<ul class="navbar-nav">
<!-- Additional items on the left -->
<li class="nav-item">
<a class="nav-link" href="#">Item 1</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Item 2</a>
</li>
<!-- Add more items as needed -->
{#<li class="nav-item">#}
{# <a class="nav-link" href="#">Item 1</a>#}
{#</li>#}
{#<li class="nav-item">#}
{# <a class="nav-link" href="#">Item 2</a>#}
{#</li>#}
</ul>
</div>
<!-- Right-aligned login/logout links -->
<div class="collapse navbar-collapse justify-content-end" id="navbarRight">
<div class="collapse navbar-collapse justify-content-end">
<ul class="navbar-nav">
{% if request.user.is_authenticated %}
<li class="nav-item">
<a class="nav-link" href="{% url 'me' %}">Profile</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'logout' %}">Logout</a>
</li>

View file

@ -0,0 +1,2 @@
{% extends "facturio/base.html" %}

View file

@ -1,4 +1,3 @@
<!-- Vaše faktura s aktualizacemi -->
<!DOCTYPE html>
<html lang="cs">
<head>