Compare commits
8 Commits
f06b72343b
...
validate-t
| Author | SHA1 | Date | |
|---|---|---|---|
| fc6b3a7fa0 | |||
| 2fc2d07a7d | |||
| 178377cfb6 | |||
| af61d45fa4 | |||
| 7c20d4d23e | |||
| 4ca502c6bc | |||
| 4c7b18d07b | |||
| 1456ba8538 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -2,5 +2,5 @@
|
|||||||
/.vscode
|
/.vscode
|
||||||
/.venv
|
/.venv
|
||||||
__pycache__
|
__pycache__
|
||||||
/db.sqlite3
|
|
||||||
/project/settings_local.py
|
/project/settings_local.py
|
||||||
|
/db.sqlite3
|
||||||
|
|||||||
BIN
db.template.sqlite3
Normal file
BIN
db.template.sqlite3
Normal file
Binary file not shown.
@ -1,6 +1,21 @@
|
|||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
|
||||||
class MainConfig(AppConfig):
|
class MainConfig(AppConfig):
|
||||||
default_auto_field = "django.db.models.BigAutoField"
|
default_auto_field = "django.db.models.BigAutoField"
|
||||||
name = "main"
|
name = "project.main"
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
"""copy template database if db not exists"""
|
||||||
|
|
||||||
|
db_fname = settings.DATABASES["default"]["NAME"]
|
||||||
|
template_db_fname = settings.BASE_DIR / "db.template.sqlite3"
|
||||||
|
|
||||||
|
if os.path.exists(db_fname):
|
||||||
|
return
|
||||||
|
|
||||||
|
shutil.copyfile(template_db_fname, db_fname)
|
||||||
|
|||||||
34
project/main/migrations/0001_initial.py
Normal file
34
project/main/migrations/0001_initial.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# Generated by Django 5.0.4 on 2024-05-14 20:16
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = []
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name="CatBreed",
|
||||||
|
fields=[
|
||||||
|
(
|
||||||
|
"id",
|
||||||
|
models.BigAutoField(
|
||||||
|
auto_created=True,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
verbose_name="ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("name", models.CharField(max_length=100)),
|
||||||
|
("country", models.CharField(max_length=100)),
|
||||||
|
("origin", models.CharField(max_length=100)),
|
||||||
|
("coat", models.CharField(max_length=100)),
|
||||||
|
("pattern", models.CharField(max_length=100)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
"db_table": "cat_breeds",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
717
project/main/migrations/0002_example_data.py
Normal file
717
project/main/migrations/0002_example_data.py
Normal file
@ -0,0 +1,717 @@
|
|||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Breed:
|
||||||
|
name: str
|
||||||
|
country: str
|
||||||
|
origin: str
|
||||||
|
coat: str
|
||||||
|
pattern: str
|
||||||
|
|
||||||
|
|
||||||
|
cat_breeds = [
|
||||||
|
Breed(
|
||||||
|
name="Abyssinian",
|
||||||
|
country="Ethiopia",
|
||||||
|
origin="Natural/Standard",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Ticked",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Aegean",
|
||||||
|
country="Greece",
|
||||||
|
origin="Natural/Standard",
|
||||||
|
coat="Semi-long",
|
||||||
|
pattern="Bi- or tri-colored",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="American Curl",
|
||||||
|
country="United States",
|
||||||
|
origin="Mutation",
|
||||||
|
coat="Short/Long",
|
||||||
|
pattern="All",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="American Bobtail",
|
||||||
|
country="United States",
|
||||||
|
origin="Mutation",
|
||||||
|
coat="Short/Long",
|
||||||
|
pattern="All",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="American Shorthair",
|
||||||
|
country="United States",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Short",
|
||||||
|
pattern="All but colorpoint",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="American Wirehair",
|
||||||
|
country="United States",
|
||||||
|
origin="Mutation",
|
||||||
|
coat="Rex",
|
||||||
|
pattern="All but colorpoint",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Arabian Mau",
|
||||||
|
country="Arabian Peninsula",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Short",
|
||||||
|
pattern="",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Australian Mist",
|
||||||
|
country="Australia",
|
||||||
|
origin="Crossbreed",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Spotted and Classic tabby",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Asian",
|
||||||
|
country="United Kingdom",
|
||||||
|
origin="",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Evenly solid",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Asian Semi-longhair",
|
||||||
|
country="United Kingdom",
|
||||||
|
origin="Crossbreed",
|
||||||
|
coat="Semi-long",
|
||||||
|
pattern="Solid",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Balinese",
|
||||||
|
country="United States",
|
||||||
|
origin="Crossbreed",
|
||||||
|
coat="Long",
|
||||||
|
pattern="Colorpoint",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Bambino",
|
||||||
|
country="United States",
|
||||||
|
origin="Crossbreed",
|
||||||
|
coat="Hairless/Furry down",
|
||||||
|
pattern="",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Bengal",
|
||||||
|
country="United States",
|
||||||
|
origin="Hybrid",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Spotted/Marbled",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Birman",
|
||||||
|
country="France",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Semi Long",
|
||||||
|
pattern="Colorpoint",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Bombay",
|
||||||
|
country="United States",
|
||||||
|
origin="Crossbred",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Solid",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Brazilian Shorthair",
|
||||||
|
country="Brazil",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Short",
|
||||||
|
pattern="All",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="British Semi-longhair",
|
||||||
|
country="United Kingdom",
|
||||||
|
origin="",
|
||||||
|
coat="Medium",
|
||||||
|
pattern="All",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="British Shorthair",
|
||||||
|
country="United Kingdom",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Short",
|
||||||
|
pattern="All",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="British Longhair",
|
||||||
|
country="United Kingdom",
|
||||||
|
origin="",
|
||||||
|
coat="Long",
|
||||||
|
pattern="",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Burmese",
|
||||||
|
country="Burma and Thailand",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Solid",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Burmilla",
|
||||||
|
country="United Kingdom",
|
||||||
|
origin="Crossbreed",
|
||||||
|
coat="Short/Long",
|
||||||
|
pattern="",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="California Spangled",
|
||||||
|
country="United States",
|
||||||
|
origin="Crossbreed",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Spotted",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Chantilly-Tiffany",
|
||||||
|
country="United States",
|
||||||
|
origin="",
|
||||||
|
coat="",
|
||||||
|
pattern="",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Chartreux",
|
||||||
|
country="France",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Solid",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Chausie",
|
||||||
|
country="France",
|
||||||
|
origin="Hybrid",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Ticked",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Cheetoh",
|
||||||
|
country="United States",
|
||||||
|
origin="Hybrid Crossbreed",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Spotted",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Cornish Rex",
|
||||||
|
country="United Kingdom",
|
||||||
|
origin="Mutation",
|
||||||
|
coat="Rex",
|
||||||
|
pattern="All",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Cymric or Manx Longhair",
|
||||||
|
country="United Kingdom",
|
||||||
|
origin="Natural/Mutation",
|
||||||
|
coat="Long",
|
||||||
|
pattern="",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Cyprus",
|
||||||
|
country="Cyprus",
|
||||||
|
origin="Natural",
|
||||||
|
coat="All",
|
||||||
|
pattern="All",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Devon Rex",
|
||||||
|
country="United Kingdom",
|
||||||
|
origin="Mutation",
|
||||||
|
coat="Rex",
|
||||||
|
pattern="All",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Donskoy, or Don Sphynx",
|
||||||
|
country="Russia",
|
||||||
|
origin="",
|
||||||
|
coat="Hairless",
|
||||||
|
pattern="",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Dragon Li",
|
||||||
|
country="China",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Striped tabby",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Dwarf cat, or Dwelf",
|
||||||
|
country="",
|
||||||
|
origin="Crossbreed",
|
||||||
|
coat="",
|
||||||
|
pattern="Hairless",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Egyptian Mau",
|
||||||
|
country="Egypt",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Spotted",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="European Shorthair",
|
||||||
|
country="Finland and Sweden",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Short",
|
||||||
|
pattern="",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Exotic Shorthair",
|
||||||
|
country="United States",
|
||||||
|
origin="Crossbreed",
|
||||||
|
coat="Short",
|
||||||
|
pattern="All",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Foldex[4]",
|
||||||
|
country="Canada",
|
||||||
|
origin="Crossbreed",
|
||||||
|
coat="Short",
|
||||||
|
pattern="All",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="German Rex",
|
||||||
|
country="East Germany",
|
||||||
|
origin="Mutation",
|
||||||
|
coat="Rex",
|
||||||
|
pattern="",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Havana Brown",
|
||||||
|
country="United Kingdom",
|
||||||
|
origin="",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Solid",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Highlander",
|
||||||
|
country="United States",
|
||||||
|
origin="Crossbreed",
|
||||||
|
coat="Short/Long",
|
||||||
|
pattern="All",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Himalayan, or Colorpoint Persian",
|
||||||
|
country="United States/United Kingdom",
|
||||||
|
origin="Crossbreed",
|
||||||
|
coat="Long",
|
||||||
|
pattern="Colorpoint",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Japanese Bobtail",
|
||||||
|
country="Japan",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Short/Long",
|
||||||
|
pattern="All but colorpoint and ticked",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Javanese",
|
||||||
|
country="United States",
|
||||||
|
origin="Crossbreed",
|
||||||
|
coat="Long/Short",
|
||||||
|
pattern="Colorpoint",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Karelian Bobtail",
|
||||||
|
country="Western Russia",
|
||||||
|
origin="Natural",
|
||||||
|
coat="",
|
||||||
|
pattern="",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Khao Manee",
|
||||||
|
country="Thailand",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Solid",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Korat",
|
||||||
|
country="Thailand",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Solid",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Korean Bobtail",
|
||||||
|
country="Korea",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Short/Long",
|
||||||
|
pattern="Colorprint",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Korn Ja",
|
||||||
|
country="Thailand",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Short/Hairless",
|
||||||
|
pattern="Solid",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Kurilian Bobtail, or Kuril Islands Bobtail",
|
||||||
|
country="Eastern Russia,Japan",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Short/Long",
|
||||||
|
pattern="",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="LaPerm",
|
||||||
|
country="United States",
|
||||||
|
origin="Mutation",
|
||||||
|
coat="Rex",
|
||||||
|
pattern="All",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Lykoi",
|
||||||
|
country="United States",
|
||||||
|
origin="Natural/Mutation",
|
||||||
|
coat="Partly Hairless",
|
||||||
|
pattern="Ticked",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Maine Coon",
|
||||||
|
country="United States",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Long",
|
||||||
|
pattern="All but colorpoint and ticked",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Manx",
|
||||||
|
country="United Kingdom",
|
||||||
|
origin="Mutation",
|
||||||
|
coat="Short/Long",
|
||||||
|
pattern="All but colorpoint",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Mekong Bobtail",
|
||||||
|
country="Russia",
|
||||||
|
origin="Natural/Mutation",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Colorpoint",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Minskin",
|
||||||
|
country="United States",
|
||||||
|
origin="Crossbreed",
|
||||||
|
coat="Short/Hairless",
|
||||||
|
pattern="All",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Munchkin",
|
||||||
|
country="United States",
|
||||||
|
origin="Mutation",
|
||||||
|
coat="",
|
||||||
|
pattern="",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Nebelung",
|
||||||
|
country="United States",
|
||||||
|
origin="",
|
||||||
|
coat="Semi-long",
|
||||||
|
pattern="Solid",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Napoleon",
|
||||||
|
country="",
|
||||||
|
origin="",
|
||||||
|
coat="Long/short",
|
||||||
|
pattern="Varied",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Norwegian Forest cat",
|
||||||
|
country="Norway",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Long",
|
||||||
|
pattern="All but colorpoint",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Ocicat",
|
||||||
|
country="United States",
|
||||||
|
origin="Crossbreed",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Spotted",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Ojos Azules",
|
||||||
|
country="United States",
|
||||||
|
origin="",
|
||||||
|
coat="",
|
||||||
|
pattern="",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Oregon Rex",
|
||||||
|
country="United States",
|
||||||
|
origin="Mutation",
|
||||||
|
coat="Rex",
|
||||||
|
pattern="",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Oriental Bicolor",
|
||||||
|
country="",
|
||||||
|
origin="",
|
||||||
|
coat="",
|
||||||
|
pattern="Bicolor",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Oriental Shorthair",
|
||||||
|
country="",
|
||||||
|
origin="",
|
||||||
|
coat="Short",
|
||||||
|
pattern="All but colorpoint",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Oriental Longhair",
|
||||||
|
country="",
|
||||||
|
origin="",
|
||||||
|
coat="Semi-long",
|
||||||
|
pattern="",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="PerFoldæ(Experimental Breed - WCF),",
|
||||||
|
country="Europe",
|
||||||
|
origin="Crossbreed",
|
||||||
|
coat="Long",
|
||||||
|
pattern="All",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Persian (Modern Persian Cat),",
|
||||||
|
country="Iran (Persia),",
|
||||||
|
origin="Crossbreed",
|
||||||
|
coat="Long",
|
||||||
|
pattern="All",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Persian (Traditional Persian Cat),",
|
||||||
|
country="Greater Iran",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Long",
|
||||||
|
pattern="All",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Peterbald",
|
||||||
|
country="Russia",
|
||||||
|
origin="Crossbreed",
|
||||||
|
coat="Hairless",
|
||||||
|
pattern="All",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Pixie-bob",
|
||||||
|
country="United States",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Spotted",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Raas",
|
||||||
|
country="Indonesia",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Short",
|
||||||
|
pattern="",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Ragamuffin",
|
||||||
|
country="United States",
|
||||||
|
origin="Crossbreed",
|
||||||
|
coat="Long",
|
||||||
|
pattern="All",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Ragdoll",
|
||||||
|
country="United States",
|
||||||
|
origin="Crossbreed",
|
||||||
|
coat="Long",
|
||||||
|
pattern="Colorpoint/Mitted/Bicolor",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Russian Blue",
|
||||||
|
country="Russia",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Solid",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Russian White, Black and Tabby",
|
||||||
|
country="Australia",
|
||||||
|
origin="Crossbreed",
|
||||||
|
coat="Short",
|
||||||
|
pattern="",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Sam Sawet",
|
||||||
|
country="Thailand",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Solid",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Savannah",
|
||||||
|
country="United States",
|
||||||
|
origin="Hybrid",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Spotted",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Scottish Fold",
|
||||||
|
country="United Kingdom",
|
||||||
|
origin="Natural/Mutation",
|
||||||
|
coat="Short/Long",
|
||||||
|
pattern="All",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Selkirk Rex",
|
||||||
|
country="United States",
|
||||||
|
origin="Mutation/Cross",
|
||||||
|
coat="Rex (Short/Long),",
|
||||||
|
pattern="All",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Serengeti",
|
||||||
|
country="United States",
|
||||||
|
origin="Hybrid Crossbreed",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Spotted",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Serrade petit",
|
||||||
|
country="France",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Short",
|
||||||
|
pattern="",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Siamese",
|
||||||
|
country="Thailand",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Colorpoint",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Siberian",
|
||||||
|
country="Russia",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Semi-long",
|
||||||
|
pattern="All",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Singapura",
|
||||||
|
country="Singapore",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Ticked",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Snowshoe",
|
||||||
|
country="United States",
|
||||||
|
origin="Crossbreed",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Colorpoint",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Sokoke",
|
||||||
|
country="Kenya",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Classic tabby with ticking",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Somali",
|
||||||
|
country="Somalia",
|
||||||
|
origin="Mutation",
|
||||||
|
coat="Long",
|
||||||
|
pattern="Ticked",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Sphynx",
|
||||||
|
country="Canada",
|
||||||
|
origin="Mutation",
|
||||||
|
coat="Hairless",
|
||||||
|
pattern="All",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Suphalak",
|
||||||
|
country="Thailand",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Solid",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Thai",
|
||||||
|
country="Thailand",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Colorpoint",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Thai Lilac",
|
||||||
|
country="Thailand",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Solid",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Tonkinese",
|
||||||
|
country="Canada",
|
||||||
|
origin="Crossbreed",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Colorpoint/Mink/Solid",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Toyger",
|
||||||
|
country="United States",
|
||||||
|
origin="Crossbreed",
|
||||||
|
coat="Short",
|
||||||
|
pattern="Mackerel",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Turkish Angora",
|
||||||
|
country="Turkey",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Semi-long",
|
||||||
|
pattern="All but colorpoint",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="Ukrainian Levkoy",
|
||||||
|
country="Ukraine",
|
||||||
|
origin="",
|
||||||
|
coat="Hairless",
|
||||||
|
pattern="",
|
||||||
|
),
|
||||||
|
Breed(
|
||||||
|
name="York Chocolate",
|
||||||
|
country="United States",
|
||||||
|
origin="Natural",
|
||||||
|
coat="Long",
|
||||||
|
pattern="Solid",
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def create_cat_breeds(apps, schema_editor):
|
||||||
|
CatBreed = apps.get_model("main", "CatBreed")
|
||||||
|
|
||||||
|
bulk = []
|
||||||
|
|
||||||
|
for cat_breed in cat_breeds:
|
||||||
|
bulk.append(
|
||||||
|
CatBreed(
|
||||||
|
name=cat_breed.name,
|
||||||
|
country=cat_breed.country,
|
||||||
|
origin=cat_breed.origin,
|
||||||
|
coat=cat_breed.coat,
|
||||||
|
pattern=cat_breed.pattern,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
CatBreed.objects.bulk_create(bulk)
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("main", "0001_initial"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RunPython(create_cat_breeds),
|
||||||
|
]
|
||||||
60
project/main/migrations/0003_person.py
Normal file
60
project/main/migrations/0003_person.py
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
def create_persons_data(apps, schema_editor):
|
||||||
|
Person = apps.get_model("main", "Person")
|
||||||
|
|
||||||
|
bulk = [
|
||||||
|
Person(
|
||||||
|
name="Pero",
|
||||||
|
address="Perina ulica 15",
|
||||||
|
city="Zagreb",
|
||||||
|
),
|
||||||
|
Person(
|
||||||
|
name="Mirko",
|
||||||
|
address="Mirkova ulica 17",
|
||||||
|
city="Zagreb",
|
||||||
|
),
|
||||||
|
Person(
|
||||||
|
name="Šime",
|
||||||
|
address="Šimina ulica 19",
|
||||||
|
city="Split",
|
||||||
|
),
|
||||||
|
Person(
|
||||||
|
name="Furio",
|
||||||
|
address="Furiozna ulica 21",
|
||||||
|
city="Pula",
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
Person.objects.bulk_create(bulk)
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("main", "0002_example_data"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name="Person",
|
||||||
|
fields=[
|
||||||
|
(
|
||||||
|
"id",
|
||||||
|
models.BigAutoField(
|
||||||
|
auto_created=True,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
verbose_name="ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("name", models.CharField(max_length=100)),
|
||||||
|
("address", models.CharField(max_length=100)),
|
||||||
|
("city", models.CharField(max_length=100)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
"db_table": "persons",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.RunPython(create_persons_data),
|
||||||
|
]
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
# Generated by Django 5.0.4 on 2024-05-16 05:33
|
||||||
|
|
||||||
|
import django.core.validators
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("main", "0003_person"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="person",
|
||||||
|
name="address",
|
||||||
|
field=models.CharField(
|
||||||
|
max_length=100,
|
||||||
|
validators=[
|
||||||
|
django.core.validators.MinLengthValidator(2),
|
||||||
|
django.core.validators.MaxLengthValidator(100),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="person",
|
||||||
|
name="city",
|
||||||
|
field=models.CharField(
|
||||||
|
max_length=100,
|
||||||
|
validators=[
|
||||||
|
django.core.validators.MinLengthValidator(2),
|
||||||
|
django.core.validators.MaxLengthValidator(100),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="person",
|
||||||
|
name="name",
|
||||||
|
field=models.CharField(
|
||||||
|
max_length=100,
|
||||||
|
validators=[
|
||||||
|
django.core.validators.MinLengthValidator(2),
|
||||||
|
django.core.validators.MaxLengthValidator(100),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -1,3 +0,0 @@
|
|||||||
from django.db import models
|
|
||||||
|
|
||||||
# Create your models here.
|
|
||||||
2
project/main/models/__init__.py
Normal file
2
project/main/models/__init__.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
from .cat_breed import CatBreed
|
||||||
|
from .person import Person
|
||||||
12
project/main/models/cat_breed.py
Normal file
12
project/main/models/cat_breed.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
class CatBreed(models.Model):
|
||||||
|
name = models.CharField(max_length=100)
|
||||||
|
country = models.CharField(max_length=100)
|
||||||
|
origin = models.CharField(max_length=100)
|
||||||
|
coat = models.CharField(max_length=100)
|
||||||
|
pattern = models.CharField(max_length=100)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
db_table = "cat_breeds"
|
||||||
26
project/main/models/person.py
Normal file
26
project/main/models/person.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
from django.core.validators import MaxLengthValidator, MinLengthValidator
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
class Person(models.Model):
|
||||||
|
name = models.CharField(
|
||||||
|
max_length=100,
|
||||||
|
blank=False,
|
||||||
|
null=False,
|
||||||
|
validators=[MinLengthValidator(2), MaxLengthValidator(100)],
|
||||||
|
)
|
||||||
|
address = models.CharField(
|
||||||
|
max_length=100,
|
||||||
|
blank=False,
|
||||||
|
null=False,
|
||||||
|
validators=[MinLengthValidator(2), MaxLengthValidator(100)],
|
||||||
|
)
|
||||||
|
city = models.CharField(
|
||||||
|
max_length=100,
|
||||||
|
blank=False,
|
||||||
|
null=False,
|
||||||
|
validators=[MinLengthValidator(2), MaxLengthValidator(100)],
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
db_table = "persons"
|
||||||
@ -6,6 +6,7 @@
|
|||||||
content="width=100%, user-scalable=yes, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
content="width=100%, user-scalable=yes, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.min.js" integrity="sha384-BBtl+eGJRgqQAUMxJ7pMwbEyER4l1g+O15P+16Ep7Q9Q+zqX6gSbd85u4mG4QzX+" crossorigin="anonymous"></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.min.js" integrity="sha384-BBtl+eGJRgqQAUMxJ7pMwbEyER4l1g+O15P+16Ep7Q9Q+zqX6gSbd85u4mG4QzX+" crossorigin="anonymous"></script>
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
||||||
<script src="https://unpkg.com/htmx.org@1.9.11" integrity="sha384-0gxUXCCR8yv9FM2b+U3FDbsKthCI66oH5IA9fHppQq9DDMHuMauqq1ZHBpJxQ0J0" crossorigin="anonymous"></script>
|
<script src="https://unpkg.com/htmx.org@1.9.11" integrity="sha384-0gxUXCCR8yv9FM2b+U3FDbsKthCI66oH5IA9fHppQq9DDMHuMauqq1ZHBpJxQ0J0" crossorigin="anonymous"></script>
|
||||||
<title>{{ title or "Django-html demo" }}</title>
|
<title>{{ title or "Django-html demo" }}</title>
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
56
project/main/templates/main/components/inline_table_row.html
Normal file
56
project/main/templates/main/components/inline_table_row.html
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
{% macro inline_table_row(person, is_editing, errors={}) %}
|
||||||
|
{% macro render_input(field_name, value) %}
|
||||||
|
{% set has_error = field_name in errors %}
|
||||||
|
<input
|
||||||
|
class="form-control {% if has_error %}is-invalid{% endif %}"
|
||||||
|
name="{{ field_name }}"
|
||||||
|
value="{{ value }}"
|
||||||
|
{% if has_error %}title="{{ errors[field_name] }}"{% endif %}
|
||||||
|
>
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% if is_editing %}
|
||||||
|
<tr id="person-row-{{ person.pk }}" hx-target="this" hx-swap="outerHTML">
|
||||||
|
<td>
|
||||||
|
{{ render_input(field_name="name", value=person.name) }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ render_input(field_name="address", value=person.address) }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ render_input(field_name="city", value=person.city) }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button
|
||||||
|
class="btn btn-outline-success"
|
||||||
|
hx-post="{{ url("table-inline-edit-row", pk=person.pk) }}"
|
||||||
|
hx-include="#person-row-{{ person.pk }} input"
|
||||||
|
>
|
||||||
|
<i class="bi bi-check-circle-fill"></i>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="btn btn-outline-danger"
|
||||||
|
hx-get="{{ url("table-inline-edit-row", pk=person.pk) }}"
|
||||||
|
hx-vals='{"action": "cancel"}'
|
||||||
|
>
|
||||||
|
<i class="bi bi-x-circle-fill"></i>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% else %}
|
||||||
|
<tr hx-target="this" hx-swap="outerHTML">
|
||||||
|
<td>{{ person.name }}</td>
|
||||||
|
<td>{{ person.address }}</td>
|
||||||
|
<td>{{ person.city }}</td>
|
||||||
|
<td>
|
||||||
|
<button
|
||||||
|
class="btn btn-outline-primary"
|
||||||
|
hx-get="{{ url("table-inline-edit-row", pk=person.pk) }}"
|
||||||
|
|
||||||
|
>
|
||||||
|
<i class="bi bi-pencil-square"></i>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
{% endmacro %}
|
||||||
@ -1,23 +1,15 @@
|
|||||||
{% macro no_js_alert() %}
|
{% macro no_js_alert() %}
|
||||||
<div class="alert alert-success d-flex align-items-center mb-5" role="alert">
|
<div class="alert alert-success d-flex align-items-center mb-5" role="alert">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="text-success me-3" viewBox="0 0 16 16">
|
<i class="bi bi-check-circle-fill me-3"></i>
|
||||||
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z"/>
|
|
||||||
</svg>
|
|
||||||
<div>
|
|
||||||
No JavaScript is used creating this page.
|
No JavaScript is used creating this page.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
{% macro js_alert(content) %}
|
{% macro js_alert(content) %}
|
||||||
<div class="alert alert-warning d-flex align-items-center mb-5" role="alert">
|
<div class="alert alert-warning d-flex align-items-center mb-5" role="alert">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="text-warning me-3" viewBox="0 0 16 16">
|
<i class="bi bi-exclamation-triangle-fill me-3"></i>
|
||||||
<path d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z"/>
|
|
||||||
</svg>
|
|
||||||
<div>
|
|
||||||
{{ content }}
|
{{ content }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
{% macro js_alert_work_in_progress() %}
|
{% macro js_alert_work_in_progress() %}
|
||||||
|
|||||||
@ -1,7 +1,54 @@
|
|||||||
{% extends "main/base/layout.html" %}
|
{% extends "main/base/layout.html" %}
|
||||||
{% from "main/components/js_alert.html" import js_alert_work_in_progress %}
|
{% from "main/components/js_alert.html" import no_js_alert %}
|
||||||
|
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{{ js_alert_work_in_progress() }}
|
{{ no_js_alert() }}
|
||||||
|
|
||||||
|
<div class="card mb-2">
|
||||||
|
<div class="card-body">
|
||||||
|
<form
|
||||||
|
class="row g-3 align-items-center"
|
||||||
|
>
|
||||||
|
<div class="col-auto">
|
||||||
|
<label class="form-label mb-0">Breed:</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-auto">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="breed"
|
||||||
|
class="form-control"
|
||||||
|
hx-get="{{ url("filter-list-filter") }}"
|
||||||
|
hx-target="#cat-breeds-table"
|
||||||
|
hx-trigger="keyup"
|
||||||
|
hx-include="select[name='country']"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col-auto">
|
||||||
|
<label class="form-label mb-0">Country:</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-auto">
|
||||||
|
<select
|
||||||
|
name="country"
|
||||||
|
class="form-select"
|
||||||
|
hx-get="{{ url("filter-list-filter") }}"
|
||||||
|
hx-target="#cat-breeds-table"
|
||||||
|
hx-trigger="change"
|
||||||
|
hx-include="input[name='breed']"
|
||||||
|
>
|
||||||
|
<option value="">
|
||||||
|
- All -
|
||||||
|
</option>
|
||||||
|
{% for country in countries %}
|
||||||
|
<option value="{{ country }}">
|
||||||
|
{{ country }}
|
||||||
|
</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% include "main/filter_list_content.html" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
22
project/main/templates/main/filter_list_content.html
Normal file
22
project/main/templates/main/filter_list_content.html
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<table class="table" id="cat-breeds-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Breed</th>
|
||||||
|
<th>Country</th>
|
||||||
|
<th>Origin</th>
|
||||||
|
<th>Coat</th>
|
||||||
|
<th>Pattern</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for breed in cat_breeds %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ breed.name }}</td>
|
||||||
|
<td>{{ breed.country }}</td>
|
||||||
|
<td>{{ breed.origin }}</td>
|
||||||
|
<td>{{ breed.coat }}</td>
|
||||||
|
<td>{{ breed.pattern }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
@ -1,7 +1,24 @@
|
|||||||
{% extends "main/base/layout.html" %}
|
{% extends "main/base/layout.html" %}
|
||||||
{% from "main/components/js_alert.html" import js_alert_work_in_progress %}
|
{% from "main/components/js_alert.html" import no_js_alert %}
|
||||||
|
{% from "main/components/inline_table_row.html" import inline_table_row %}
|
||||||
|
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{{ js_alert_work_in_progress() }}
|
{{ no_js_alert() }}
|
||||||
|
|
||||||
|
<table class="table align-middle">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="width: 25%">Name</th>
|
||||||
|
<th>Address</th>
|
||||||
|
<th style="width: 25%">City</th>
|
||||||
|
<th style="width: 15%"> </th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for person in persons %}
|
||||||
|
{{ inline_table_row(person, is_editing=False) }}
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
3
project/main/templates/main/table_inline_table_row.html
Normal file
3
project/main/templates/main/table_inline_table_row.html
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{% from "main/components/inline_table_row.html" import inline_table_row %}
|
||||||
|
|
||||||
|
{{ inline_table_row(person, is_editing=is_editing, errors=errors) }}
|
||||||
@ -4,8 +4,8 @@ from .complex_form.views import (
|
|||||||
RouteModuleHandleView,
|
RouteModuleHandleView,
|
||||||
WarehouseManagementHandleView,
|
WarehouseManagementHandleView,
|
||||||
)
|
)
|
||||||
from .filter_list import FilterListView
|
from .filter_list import FilterListFilterView, FilterListView
|
||||||
from .form_validation import FormValidationView
|
from .form_validation import FormValidationView
|
||||||
from .home import HomeView
|
from .home import HomeView
|
||||||
from .swap import SwapView
|
from .swap import SwapView
|
||||||
from .table_inline_edit import TableInlineEditView
|
from .table_inline_edit import TableInlineEditView, TableInlineEditRowView
|
||||||
|
|||||||
@ -1,7 +1,65 @@
|
|||||||
|
from typing import Any, Optional
|
||||||
|
|
||||||
|
from django.db.models import Count, Q
|
||||||
|
|
||||||
|
from project.main.models import CatBreed
|
||||||
from project.main.views.demo_view_base import DemoViewBase
|
from project.main.views.demo_view_base import DemoViewBase
|
||||||
|
|
||||||
|
|
||||||
|
def get_countries() -> list[str]:
|
||||||
|
ann = (
|
||||||
|
CatBreed.objects.values("country")
|
||||||
|
.annotate(Count("country"))
|
||||||
|
.order_by("country")
|
||||||
|
)
|
||||||
|
return [a["country"] for a in ann]
|
||||||
|
|
||||||
|
|
||||||
|
def filter_cat_breeds(
|
||||||
|
breed_filter: Optional[str] = None, country_filter: Optional[str] = None
|
||||||
|
) -> list[CatBreed]:
|
||||||
|
q = Q()
|
||||||
|
|
||||||
|
if breed_filter:
|
||||||
|
q &= Q(name__icontains=breed_filter)
|
||||||
|
if country_filter:
|
||||||
|
q &= Q(country=country_filter)
|
||||||
|
|
||||||
|
return CatBreed.objects.filter(q).order_by("name")
|
||||||
|
|
||||||
|
|
||||||
class FilterListView(DemoViewBase):
|
class FilterListView(DemoViewBase):
|
||||||
template_name = "main/filter_list.html"
|
template_name = "main/filter_list.html"
|
||||||
active_section = "filter-list"
|
active_section = "filter-list"
|
||||||
title = "Filter List"
|
title = "Filter List"
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs) -> dict[str, Any]:
|
||||||
|
context_data = super().get_context_data(**kwargs)
|
||||||
|
|
||||||
|
context_data.update(
|
||||||
|
{
|
||||||
|
"cat_breeds": filter_cat_breeds(),
|
||||||
|
"countries": get_countries(),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return context_data
|
||||||
|
|
||||||
|
|
||||||
|
class FilterListFilterView(DemoViewBase):
|
||||||
|
template_name = "main/filter_list_content.html"
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs) -> dict[str, Any]:
|
||||||
|
context_data = super().get_context_data(**kwargs)
|
||||||
|
|
||||||
|
cat_breeds = filter_cat_breeds(
|
||||||
|
breed_filter=self.request.GET.get("breed"),
|
||||||
|
country_filter=self.request.GET.get("country"),
|
||||||
|
)
|
||||||
|
|
||||||
|
context_data.update(
|
||||||
|
{
|
||||||
|
"cat_breeds": cat_breeds,
|
||||||
|
"countries": get_countries(),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return context_data
|
||||||
|
|||||||
@ -1,7 +1,79 @@
|
|||||||
|
from typing import Any, Optional
|
||||||
|
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
|
from django.core.handlers.wsgi import WSGIRequest
|
||||||
|
from django.http import Http404, HttpResponse
|
||||||
|
from django.shortcuts import render
|
||||||
|
|
||||||
|
from project.main.models import Person
|
||||||
from project.main.views.demo_view_base import DemoViewBase
|
from project.main.views.demo_view_base import DemoViewBase
|
||||||
|
|
||||||
|
|
||||||
|
def get_person(pk: int) -> Person:
|
||||||
|
try:
|
||||||
|
return Person.objects.get(pk=pk)
|
||||||
|
except Person.DoesNotExist:
|
||||||
|
raise Http404("Person not found")
|
||||||
|
|
||||||
|
|
||||||
class TableInlineEditView(DemoViewBase):
|
class TableInlineEditView(DemoViewBase):
|
||||||
template_name = "main/table_inline_edit.html"
|
template_name = "main/table_inline_edit.html"
|
||||||
active_section = "table-inline-edit"
|
active_section = "table-inline-edit"
|
||||||
title = "Table Inline Edit"
|
title = "Table Inline Edit"
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs) -> dict[str, Any]:
|
||||||
|
context_data = super().get_context_data(**kwargs)
|
||||||
|
|
||||||
|
persons = Person.objects.all()
|
||||||
|
|
||||||
|
context_data.update(
|
||||||
|
{
|
||||||
|
"persons": persons,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return context_data
|
||||||
|
|
||||||
|
|
||||||
|
class TableInlineEditRowView(DemoViewBase):
|
||||||
|
template_name = "main/table_inline_table_row.html"
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs) -> dict[str, Any]:
|
||||||
|
context_data = super().get_context_data(**kwargs)
|
||||||
|
|
||||||
|
person = get_person(pk=kwargs.get("pk"))
|
||||||
|
action = self.request.GET.get("action", "edit")
|
||||||
|
|
||||||
|
context_data.update(
|
||||||
|
{
|
||||||
|
"person": person,
|
||||||
|
"is_editing": action == "edit",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return context_data
|
||||||
|
|
||||||
|
def post(self, request: WSGIRequest, *args, **kwargs) -> HttpResponse:
|
||||||
|
errors: Optional[dict[str, str]] = None
|
||||||
|
|
||||||
|
person = get_person(pk=kwargs.get("pk"))
|
||||||
|
person.name = request.POST.get("name")
|
||||||
|
person.address = request.POST.get("address")
|
||||||
|
person.city = request.POST.get("city")
|
||||||
|
|
||||||
|
try:
|
||||||
|
person.clean_fields()
|
||||||
|
except ValidationError as ex:
|
||||||
|
errors = {key: value[0].message for key, value in ex.error_dict.items()}
|
||||||
|
else:
|
||||||
|
person.save()
|
||||||
|
|
||||||
|
print(errors)
|
||||||
|
|
||||||
|
return render(
|
||||||
|
context={
|
||||||
|
"person": person,
|
||||||
|
"errors": errors,
|
||||||
|
"is_editing": errors is not None,
|
||||||
|
},
|
||||||
|
template_name=self.template_name,
|
||||||
|
request=request,
|
||||||
|
)
|
||||||
|
|||||||
@ -37,6 +37,7 @@ INSTALLED_APPS = [
|
|||||||
"django.contrib.sessions",
|
"django.contrib.sessions",
|
||||||
"django.contrib.messages",
|
"django.contrib.messages",
|
||||||
"django.contrib.staticfiles",
|
"django.contrib.staticfiles",
|
||||||
|
"project.main",
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
|
|||||||
@ -6,10 +6,12 @@ urlpatterns = [
|
|||||||
path("", views.HomeView.as_view(), name="home"),
|
path("", views.HomeView.as_view(), name="home"),
|
||||||
path("swap", views.SwapView.as_view(), name="swap"),
|
path("swap", views.SwapView.as_view(), name="swap"),
|
||||||
path("filter-list", views.FilterListView.as_view(), name="filter-list"),
|
path("filter-list", views.FilterListView.as_view(), name="filter-list"),
|
||||||
|
path("filter-list-filter", views.FilterListFilterView.as_view(), name="filter-list-filter"),
|
||||||
path("form-validation", views.FormValidationView.as_view(), name="form-validation"),
|
path("form-validation", views.FormValidationView.as_view(), name="form-validation"),
|
||||||
path("complex-form", views.ComplexFormView.as_view(), name="complex-form"),
|
path("complex-form", views.ComplexFormView.as_view(), name="complex-form"),
|
||||||
path("complex-form/handle/route-module", views.RouteModuleHandleView.as_view(), name="complex-form-handle-route-module"),
|
path("complex-form/handle/route-module", views.RouteModuleHandleView.as_view(), name="complex-form-handle-route-module"),
|
||||||
path("complex-form/handle/reports", views.ReportsHandleView.as_view(), name="complex-form-handle-reports"),
|
path("complex-form/handle/reports", views.ReportsHandleView.as_view(), name="complex-form-handle-reports"),
|
||||||
path("complex-form/handle/warehouse-management", views.WarehouseManagementHandleView.as_view(), name="complex-form-handle-warehouse-management"),
|
path("complex-form/handle/warehouse-management", views.WarehouseManagementHandleView.as_view(), name="complex-form-handle-warehouse-management"),
|
||||||
path("table-inline-edit", views.TableInlineEditView.as_view(), name="table-inline-edit"),
|
path("table-inline-edit", views.TableInlineEditView.as_view(), name="table-inline-edit"),
|
||||||
|
path("table-inline-edit/edit/<int:pk>", views.TableInlineEditRowView.as_view(), name="table-inline-edit-row"),
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user