Merge branch 'crispy-forms' into 'master'
Crispy forms See merge request JustScreaMy/facturio!1
This commit is contained in:
commit
8bbfb6010c
21 changed files with 172 additions and 65 deletions
|
@ -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'))
|
||||
|
|
|
@ -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"),
|
||||
),
|
||||
]
|
|
@ -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):
|
||||
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
|
||||
|
|
|
@ -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 %}
|
||||
|
|
|
@ -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 %}
|
||||
|
|
|
@ -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 %}
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
34
poetry.lock
generated
|
@ -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"
|
||||
|
|
|
@ -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
0
subjects/__init__.py
Normal file
3
subjects/admin.py
Normal file
3
subjects/admin.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
6
subjects/apps.py
Normal file
6
subjects/apps.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class SubjectsConfig(AppConfig):
|
||||
default_auto_field = "django.db.models.BigAutoField"
|
||||
name = "subjects"
|
0
subjects/migrations/__init__.py
Normal file
0
subjects/migrations/__init__.py
Normal file
3
subjects/models.py
Normal file
3
subjects/models.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
from django.db import models
|
||||
|
||||
# Create your models here.
|
3
subjects/tests.py
Normal file
3
subjects/tests.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
3
subjects/views.py
Normal file
3
subjects/views.py
Normal 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"
|
|
@ -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>
|
||||
|
|
2
templates/facturio/index.html
Normal file
2
templates/facturio/index.html
Normal file
|
@ -0,0 +1,2 @@
|
|||
{% extends "facturio/base.html" %}
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
<!-- Vaše faktura s aktualizacemi -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="cs">
|
||||
<head>
|
||||
|
|
Reference in a new issue