Skip to content

Commit 8f1c254

Browse files
committed
fix: start_app urlpattern formatting (add leading comma+newline)
fix: eliminate runtime partials/templatetags dependency from CRUD - Replace partials/table.html with inline table HTML in build_blueprint_context - Delete partials/table.html, partials/pagination.html, templatetags/falco_cli.py - CRUD now uses cotton pagination component instead of partial include - Inline table with explicit field references, heroicons for booleans/actions - Inject project_name derived from settings.ROOT_URLCONF
1 parent 84c74c0 commit 8f1c254

9 files changed

Lines changed: 88 additions & 202 deletions

File tree

src/falco_cli/management/commands/crud.py

Lines changed: 81 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ def generating_urls(
342342
root_url = root_url.strip().replace(".", "/")
343343
root_url_path = Path(f"{root_url}.py")
344344
module = parso.parse(root_url_path.read_text())
345-
new_path = parso.parse(f"path('{app.label}/', include('{app.name}.urls', namespace='{app.label}'))")
345+
new_path = parso.parse(f",\n path('{app.label}/', include('{app.name}.urls', namespace='{app.label}'))")
346346
for node in module.children:
347347
try:
348348
if (
@@ -453,11 +453,67 @@ def build_blueprint_context(
453453
delete_view_name = f"{view_name_prefix}delete"
454454
create_view_url = f"{{% url '{app_label}:{view_name_prefix}create' %}}"
455455
ordering = order_by or django_model["lookup_field"]
456+
project_name = settings.ROOT_URLCONF.rsplit(".", 1)[0]
457+
458+
fields = django_model["fields"]
459+
field_names = list(fields.keys())
460+
461+
table_headers = "".join(
462+
f"<th>{fields[f]['verbose_name']}</th>" for f in field_names
463+
)
464+
465+
table_cells = ""
466+
for idx, f in enumerate(field_names):
467+
klass = fields[f]["class_name"]
468+
if idx == 0:
469+
cell = (
470+
f'<td><a class="font-medium hover:underline" href="'
471+
f'{{% url \'{app_label}:{detail_view_name}\' object.{django_model["lookup_field"]} %}}">'
472+
f'{{{{object.{f}}}}}</a></td>'
473+
)
474+
elif klass in ("BooleanField", "NullBooleanField"):
475+
cell = (
476+
f'<td class="text-center">'
477+
f'{{% if object.{f} %}}'
478+
f'{{% heroicon_solid "check-circle" size=19 class="text-green-500 mx-auto" %}}'
479+
f'{{% else %}}'
480+
f'{{% heroicon_solid "x-circle" size=19 class="text-red-500 mx-auto" %}}'
481+
f'{{% endif %}}'
482+
f'</td>'
483+
)
484+
elif klass in ("ImageField", "FileField"):
485+
cell = (
486+
f'<td>'
487+
f'{{% if object.{f} %}}'
488+
f'<a class="hover:underline" href="{{{{object.{f}.url}}}}">{{{{object.{f}.name}}}}</a>'
489+
f'{{% endif %}}'
490+
f'</td>'
491+
)
492+
else:
493+
cell = f'<td>{{{{object.{f}}}}}</td>'
494+
table_cells += cell
495+
496+
actions_cell = (
497+
f'<td class="flex gap-3">'
498+
f'<a class="hover:text-blue-500" href="{{% url \'{app_label}:{detail_view_name}\' object.{django_model["lookup_field"]} %}}">{{% heroicon_outline "eye" size=18 %}}</a>'
499+
f'<a class="hover:text-blue-500" href="{{% url \'{app_label}:{update_view_name}\' object.{django_model["lookup_field"]} %}}">{{% heroicon_outline "pencil-square" size=18 %}}</a>'
500+
f'<form hx-boost="true" hx-target="closest tr" hx-push-url="false" '
501+
f'action="{{% url \'{app_label}:{delete_view_name}\' object.{django_model["lookup_field"]} %}}" class="cursor-pointer text-red-600 hover:text-red-500" '
502+
f'method="post" onsubmit="return confirm(\'Do you really want to delete this element?\');">'
503+
f'{{% csrf_token %}}'
504+
f'<button type="submit">{{% heroicon_outline "trash" size=18 %}}</button>'
505+
f'</form>'
506+
f'</td>'
507+
)
508+
456509
return {
510+
"project_name": project_name,
457511
"app_label": app_label,
458512
"model": django_model,
459-
"fields_tuple": tuple(django_model["fields"].keys()),
460-
"editable_fields_tuple": tuple(key for key, value in django_model["fields"].items() if value["editable"]),
513+
"fields_tuple": tuple(field_names),
514+
"editable_fields_tuple": tuple(
515+
key for key, value in fields.items() if value["editable"]
516+
),
461517
"view_name_prefix": view_name_prefix,
462518
"list_view_name": list_view_name,
463519
"detail_view_name": detail_view_name,
@@ -470,18 +526,28 @@ def build_blueprint_context(
470526
"entry_point": entry_point,
471527
"login_required": login_required,
472528
"ordering": ordering,
473-
"pagination_block": f"""
474-
{{% if {model_name_lower}s_page.paginator.num_pages > 1 %}}
475-
{{% include "partials/pagination.html" with page={model_name_lower}s_page %}}
476-
{{% endif %}}
477-
""",
478-
"table_block": f"""
479-
{{% if {model_name_lower}s_page.object_list %}}
480-
{{% include "partials/table.html" with objects={model_name_lower}s_page.object_list fields=fields detail_view="{app_label}:{detail_view_name}" delete_view="{app_label}:{delete_view_name}" update_view="{app_label}:{update_view_name}" %}}
481-
{{% else %}}
482-
<p class="mt-8">There are no {django_model["verbose_name_plural"]}. <a class="hover:underline cursor-pointer" href="{create_view_url}">Create one now?</a> </p>
483-
{{% endif %}}
484-
""",
529+
"pagination_block": (
530+
f'{{% if {model_name_lower}s_page.paginator.num_pages > 1 %}}'
531+
f'<c-pagination page={model_name_lower}s_page />'
532+
f'{{% endif %}}'
533+
),
534+
"table_block": (
535+
f'{{% if {model_name_lower}s_page.object_list %}}'
536+
f'<div class="overflow-x-auto">'
537+
f'<table class="table">'
538+
f'<caption>A list of {django_model["verbose_name_plural"]}.</caption>'
539+
f'<thead><tr>{table_headers}</tr></thead>'
540+
f'<tbody>'
541+
f'{{% for object in {model_name_lower}s_page.object_list %}}'
542+
f'<tr>{table_cells}{actions_cell}</tr>'
543+
f'{{% endfor %}}'
544+
f'</tbody>'
545+
f'</table>'
546+
f'</div>'
547+
f'{{% else %}}'
548+
f'<p class="mt-8">There are no {django_model["verbose_name_plural"]}. <a class="hover:underline cursor-pointer" href="{create_view_url}">Create one now?</a> </p>'
549+
f'{{% endif %}}'
550+
),
485551
}
486552

487553

src/falco_cli/pagination.py

Lines changed: 0 additions & 23 deletions
This file was deleted.

src/falco_cli/start_project.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
DEFAULT_SKIP = ["playground.ipynb", "README.md", "*/static/*"]
2828

2929

30-
@cappa.command(help="Initialize a new django project the falco way.")
30+
@cappa.command(help="Initialize a new django project the falco way.", aliases=["new"])
3131
class StartProject:
3232
project_name: Annotated[
3333
str,

src/falco_cli/templates/crud/list.html

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,10 @@ <h1 class="text-lg font-bold">{{ model.verbose_name_plural|capfirst }}</h1>
1616

1717
{% partialdef table inline=True %}
1818
<div id="table">
19-
<div class="flex flex-col">
20-
<div class="overflow-x-auto sm:-mx-6 lg:-mx-8">
21-
<div class="py-2 inline-block min-w-full sm:px-6 lg:px-8">
22-
<div class="overflow-x-auto">
23-
{% endverbatim %}
24-
{{ table_block|safe }}
25-
</div>
26-
</div>
27-
</div>
28-
</div>
29-
{{ pagination_block|safe }}
30-
{% verbatim %}
19+
{% endverbatim %}
20+
{{ table_block|safe }}
21+
{{ pagination_block|safe }}
22+
{% verbatim %}
3123
</div>
3224
{% endpartialdef %}
3325

src/falco_cli/templates/crud/views.py.dtl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# IMPORTS:START
22
from falco_cli.htmx import for_htmx
3-
from falco_cli.pagination import paginate_queryset
3+
from {{ project_name }}.core.utils import paginate_queryset
44
{% if login_required %}
55
from django.http import HttpRequest as AuthenticatedHttpRequest
66
{% else %}

src/falco_cli/templates/partials/pagination.html

Lines changed: 0 additions & 39 deletions
This file was deleted.

src/falco_cli/templates/partials/table.html

Lines changed: 0 additions & 73 deletions
This file was deleted.

src/falco_cli/templatetags/falco_cli.py

Lines changed: 0 additions & 37 deletions
This file was deleted.

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)