Skip to content

Commit

Permalink
first pass of pulling our changes back in
Browse files Browse the repository at this point in the history
  • Loading branch information
joshuadavidthomas committed Jul 1, 2024
1 parent a9ec3f8 commit 7d93b56
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 17 deletions.
26 changes: 16 additions & 10 deletions src/neapolitan/templatetags/neapolitan.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
from django import template
from django.urls import reverse
from django.utils.safestring import mark_safe

from neapolitan.views import Role

register = template.Library()


def action_links(view, object):
actions = [
(Role.DETAIL.reverse(view, object), "View"),
(Role.UPDATE.reverse(view, object), "Edit"),
(Role.DELETE.reverse(view, object), "Delete"),
]
links = [f"<a href='{url}'>{anchor_text}</a>" for url, anchor_text in actions]
return mark_safe(" | ".join(links))
actions = {
"detail": {
"url": Role.DETAIL.reverse(view, object),
"text": "View",
},
"update": {
"url": Role.UPDATE.reverse(view, object),
"text": "Edit",
},
"delete": {
"url": Role.DELETE.reverse(view, object),
"text": "Delete",
},
}
return actions


@register.inclusion_tag("neapolitan/partial/detail.html")
Expand Down Expand Up @@ -51,7 +57,7 @@ def object_list(objects, view):
with links to view, edit, and delete views.
"""

fields = view.fields
fields = view.get_list_fields()
headers = [objects[0]._meta.get_field(f).verbose_name for f in fields]
object_list = [
{
Expand Down
51 changes: 44 additions & 7 deletions src/neapolitan/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def get_url(self, view_cls):
return path(
self.url_pattern(view_cls),
view_cls.as_view(role=self),
name=f"{view_cls.url_base}-{self.url_name_component}"
name=f"{view_cls.url_base}-{self.url_name_component}",
)

def reverse(self, view, object=None):
Expand All @@ -98,7 +98,6 @@ def reverse(self, view, object=None):
)



class CRUDView(View):
"""
CRUDView is Neapolitan's core. It provides the standard list, detail,
Expand Down Expand Up @@ -142,9 +141,14 @@ def list(self, request, *args, **kwargs):
"""GET handler for the list view."""

queryset = self.get_queryset()
filterset = self.get_filterset(queryset)
if filterset is not None:
queryset = filterset.qs

self.filterset = self.get_filterset(queryset)
if self.filterset and (
not self.filterset.is_bound
or self.filterset.is_valid()
or not self.get_strict()
):
queryset = self.filterset.qs

if not self.allow_empty and not queryset.exists():
raise Http404
Expand All @@ -157,7 +161,7 @@ def list(self, request, *args, **kwargs):
page_obj=None,
is_paginated=False,
paginator=None,
filterset=filterset,
filter=filterset,
)
else:
# Paginated response
Expand All @@ -167,7 +171,7 @@ def list(self, request, *args, **kwargs):
page_obj=page,
is_paginated=page.has_other_pages(),
paginator=page.paginator,
filterset=filterset,
filter=filterset,
)

return self.render_to_response(context)
Expand Down Expand Up @@ -422,6 +426,39 @@ def render_to_response(self, context):
request=self.request, template=self.get_template_names(), context=context
)

# Fields

def get_fields(self):
# Construct the method name based on the current role.
# For example, if self.role is Role.LIST, method_name will be 'list_fields'.
method_name = f"{self.role}_fields"

if self.fields is not None:
# Check if the attribute (method or property) with the constructed name exists in the class.
if hasattr(self, method_name):
# If the attribute exists, check if it is callable (i.e., if it's a method).
if callable(getattr(self, method_name)):
# If it's a callable method, call the method and return its result.
return getattr(self, method_name)()
# If the attribute exists but is not callable (e.g., a property), directly return its value.
return getattr(self, method_name)

# If the specific role-based method or property does not exist, fall back to the default 'fields'.
return self.fields

msg = "'%s' must define 'fields' or override 'get_fields()'"
raise ImproperlyConfigured(msg % self.__class__.__name__)

def get_detail_fields(self):
if self.detail_fields:
return self.detail_fields
return self.fields

def get_list_fields(self):
if self.list_fields:
return self.list_fields
return self.fields

# URLs and view callables

@classonlymethod
Expand Down

0 comments on commit 7d93b56

Please sign in to comment.