Compare commits
2 Commits
4ca502c6bc
...
c7f89a9ab4
| Author | SHA1 | Date | |
|---|---|---|---|
| c7f89a9ab4 | |||
| 7c20d4d23e |
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,3 +3,4 @@
|
|||||||
/.venv
|
/.venv
|
||||||
__pycache__
|
__pycache__
|
||||||
/project/settings_local.py
|
/project/settings_local.py
|
||||||
|
/db.sqlite3
|
||||||
|
|||||||
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 = "project.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)
|
||||||
|
|||||||
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),
|
||||||
|
]
|
||||||
@ -1 +1,2 @@
|
|||||||
from .cat_breed import CatBreed
|
from .cat_breed import CatBreed
|
||||||
|
from .person import Person
|
||||||
|
|||||||
10
project/main/models/person.py
Normal file
10
project/main/models/person.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
class Person(models.Model):
|
||||||
|
name = models.CharField(max_length=100)
|
||||||
|
address = models.CharField(max_length=100)
|
||||||
|
city = models.CharField(max_length=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>
|
||||||
|
|||||||
43
project/main/templates/main/components/inline_table_row.html
Normal file
43
project/main/templates/main/components/inline_table_row.html
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
{% macro inline_table_row(person, is_editing) %}
|
||||||
|
<tr hx-target="this" hx-swap="outerHTML">
|
||||||
|
{% if is_editing %}
|
||||||
|
<td>
|
||||||
|
<input class="form-control" name="name" value="{{ person.name }}">
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input class="form-control" name="address" value="{{ person.address }}">
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input class="form-control" name="city" value="{{ person.city }}">
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button
|
||||||
|
class="btn btn-outline-success"
|
||||||
|
hx-get="{{ url("table-inline-edit-row", pk=person.pk) }}"
|
||||||
|
hx-vals='{"action": "save"}'
|
||||||
|
>
|
||||||
|
<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>
|
||||||
|
{% else %}
|
||||||
|
<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>
|
||||||
|
{% endif %}
|
||||||
|
</tr>
|
||||||
|
{% endmacro %}
|
||||||
@ -1,22 +1,14 @@
|
|||||||
{% 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"/>
|
No JavaScript is used creating this page.
|
||||||
</svg>
|
|
||||||
<div>
|
|
||||||
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"/>
|
{{ content }}
|
||||||
</svg>
|
|
||||||
<div>
|
|
||||||
{{ content }}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
|||||||
@ -50,6 +50,5 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
{% include "main/filter_list_content.html" %}
|
{% include "main/filter_list_content.html" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@ -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) }}
|
||||||
@ -8,4 +8,4 @@ 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,3 +1,8 @@
|
|||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from django.http import Http404
|
||||||
|
|
||||||
|
from project.main.models import Person
|
||||||
from project.main.views.demo_view_base import DemoViewBase
|
from project.main.views.demo_view_base import DemoViewBase
|
||||||
|
|
||||||
|
|
||||||
@ -5,3 +10,37 @@ 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)
|
||||||
|
|
||||||
|
try:
|
||||||
|
person = Person.objects.get(pk=kwargs.get("pk"))
|
||||||
|
except Person.DoesNotExist:
|
||||||
|
raise Http404("Person not found")
|
||||||
|
|
||||||
|
action = self.request.GET.get("action")
|
||||||
|
|
||||||
|
context_data.update(
|
||||||
|
{
|
||||||
|
"person": person,
|
||||||
|
"is_editing": action != "cancel",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return context_data
|
||||||
|
|||||||
@ -13,4 +13,5 @@ urlpatterns = [
|
|||||||
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