fisk/core/views/__init__.py

248 lines
8.5 KiB
Python
Raw Normal View History

import uuid
from django.http import Http404, HttpResponseBadRequest
from django.urls import reverse
from django.views.generic.detail import DetailView
from django.views.generic.edit import CreateView, DeleteView, UpdateView
from django.views.generic.list import ListView
from rest_framework.parsers import FormParser
from core.util import logs
log = logs.get_logger(__name__)
class ObjectList(ListView):
allowed_types = ["modal", "widget", "window", "page"]
window_content = "window-content/objects.html"
list_template = None
model = None
context_object_name = "objects"
2022-10-29 13:05:01 +00:00
context_object_name_singular = "object"
page_title = None
page_subtitle = None
title = "Objects"
title_singular = "Object"
2022-10-29 13:05:01 +00:00
list_url_name = None
# WARNING: TAKEN FROM locals()
list_url_args = ["type"]
submit_url_name = None
# copied from BaseListView
def get(self, request, *args, **kwargs):
self.object_list = self.get_queryset()
allow_empty = self.get_allow_empty()
type = kwargs.get("type", None)
if not type:
return HttpResponseBadRequest("No type specified")
if type not in self.allowed_types:
return HttpResponseBadRequest("Invalid type specified")
self.template_name = f"wm/{type}.html"
unique = str(uuid.uuid4())[:8]
2022-10-29 13:05:01 +00:00
list_url_args = {}
for arg in self.list_url_args:
list_url_args[arg] = locals()[arg]
print("LIST URL ARGS", list_url_args)
if type == "page":
type = "modal"
if not allow_empty:
# When pagination is enabled and object_list is a queryset,
# it's better to do a cheap query than to load the unpaginated
# queryset in memory.
if self.get_paginate_by(self.object_list) is not None and hasattr(
self.object_list, "exists"
):
is_empty = not self.object_list.exists()
else:
is_empty = not self.object_list
if is_empty:
raise Http404("Empty list")
submit_url = reverse(self.submit_url_name, kwargs={"type": type})
2022-10-29 13:05:01 +00:00
list_url = reverse(self.list_url_name, kwargs=list_url_args)
context = self.get_context_data()
context["title"] = self.title + f" ({type})"
context["title_singular"] = self.title_singular
context["unique"] = unique
context["window_content"] = self.window_content
context["list_template"] = self.list_template
context["page_title"] = self.page_title
context["page_subtitle"] = self.page_subtitle
context["type"] = type
context["submit_url"] = submit_url
2022-10-29 13:05:01 +00:00
context["list_url"] = list_url
context["context_object_name"] = self.context_object_name
context["context_object_name_singular"] = self.context_object_name_singular
# Return partials for HTMX
if self.request.htmx:
self.template_name = self.list_template
return self.render_to_response(context)
class ObjectCreate(CreateView):
allowed_types = ["modal", "widget", "window", "page"]
window_content = "window-content/object-form.html"
parser_classes = [FormParser]
model = None
context_object_name = "objects"
submit_url_name = None
2022-10-29 13:05:01 +00:00
list_url_name = None
# WARNING: TAKEN FROM locals()
list_url_args = ["type"]
request = None
def form_valid(self, form):
obj = form.save(commit=False)
if self.request is None:
raise Exception("Request is None")
obj.user = self.request.user
obj.save()
form.save_m2m()
context = {"message": "Object created", "class": "success"}
2022-10-29 13:05:01 +00:00
response = self.render_to_response(context)
response["HX-Trigger"] = f"{self.context_object_name_singular}Event"
return response
def get(self, request, *args, **kwargs):
self.request = request
type = kwargs.get("type", None)
if not type:
return HttpResponseBadRequest("No type specified")
if type not in self.allowed_types:
return HttpResponseBadRequest("Invalid type specified")
self.template_name = f"wm/{type}.html"
unique = str(uuid.uuid4())[:8]
2022-10-29 13:05:01 +00:00
list_url_args = {}
for arg in self.list_url_args:
list_url_args[arg] = locals()[arg]
print("LIST URL ARGS", list_url_args)
if type == "page":
type = "modal"
self.object = None
submit_url = reverse(self.submit_url_name, kwargs={"type": type})
2022-10-29 13:05:01 +00:00
list_url = reverse(self.list_url_name, kwargs=list_url_args)
context = self.get_context_data()
context["unique"] = unique
context["window_content"] = self.window_content
context["context_object_name"] = self.context_object_name
2022-10-29 13:05:01 +00:00
context["context_object_name_singular"] = self.context_object_name_singular
context["submit_url"] = submit_url
2022-10-29 13:05:01 +00:00
context["list_url"] = list_url
context["type"] = type
return self.render_to_response(context)
def post(self, request, *args, **kwargs):
self.request = request
self.template_name = "partials/notify.html"
return super().post(request, *args, **kwargs)
class ObjectRead(DetailView):
allowed_types = ["modal", "widget", "window", "page"]
window_content = "window-content/object.html"
model = None
context_object_name = "object"
class ObjectUpdate(UpdateView):
allowed_types = ["modal", "widget", "window", "page"]
window_content = "window-content/object-form.html"
parser_classes = [FormParser]
model = None
context_object_name = "objects"
submit_url_name = None
request = None
def form_valid(self, form):
obj = form.save(commit=False)
if self.request is None:
raise Exception("Request is None")
obj.save()
form.save_m2m()
context = {"message": "Object updated", "class": "success"}
2022-10-29 13:05:01 +00:00
response = self.render_to_response(context)
response["HX-Trigger"] = f"{self.context_object_name_singular}Event"
return response
def get(self, request, *args, **kwargs):
self.request = request
type = kwargs.get("type", None)
pk = kwargs.get("pk", None)
if not type:
return HttpResponseBadRequest("No type specified")
if not pk:
return HttpResponseBadRequest("No pk specified")
if type not in self.allowed_types:
return HttpResponseBadRequest("Invalid type specified")
self.template_name = f"wm/{type}.html"
unique = str(uuid.uuid4())[:8]
if type == "page":
type = "modal"
self.object = self.get_object()
submit_url = reverse(self.submit_url_name, kwargs={"type": type, "pk": pk})
context = self.get_context_data()
context["unique"] = unique
context["window_content"] = self.window_content
context["context_object_name"] = self.context_object_name
2022-10-29 13:05:01 +00:00
context["context_object_name_singular"] = self.context_object_name_singular
context["submit_url"] = submit_url
context["type"] = type
return self.render_to_response(context)
def post(self, request, *args, **kwargs):
self.request = request
self.template_name = "partials/notify.html"
return super().post(request, *args, **kwargs)
class ObjectDelete(DeleteView):
model = None
2022-10-29 13:05:01 +00:00
context_object_name_singular = "object"
template_name = "partials/notify.html"
# Overriden to prevent success URL from being used
def delete(self, request, *args, **kwargs):
"""
Call the delete() method on the fetched object and then redirect to the
success URL.
"""
self.object = self.get_object()
# success_url = self.get_success_url()
self.object.delete()
context = {"message": "Object deleted", "class": "success"}
2022-10-29 13:05:01 +00:00
response = self.render_to_response(context)
response["HX-Trigger"] = f"{self.context_object_name_singular}Event"
return response
# This will be used in newer Django versions, until then we get a warning
def form_valid(self, form):
"""
Call the delete() method on the fetched object.
"""
self.object = self.get_object()
self.object.delete()
context = {"message": "Object deleted", "class": "success"}
2022-10-29 13:05:01 +00:00
response = self.render_to_response(context)
response["HX-Trigger"] = f"{self.context_object_name_singular}Event"
return response