Refactoring: views now use api for ajax
This commit is contained in:
parent
e05319ec3c
commit
2e648ac4fe
@ -12,7 +12,7 @@ $(function () {
|
|||||||
const archiveListElement = $(this).attr("data-jq-archive-target");
|
const archiveListElement = $(this).attr("data-jq-archive-target");
|
||||||
const delUrl = $(this).attr("href");
|
const delUrl = $(this).attr("href");
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: "delete",
|
type: "DELETE",
|
||||||
url: delUrl,
|
url: delUrl,
|
||||||
headers: {
|
headers: {
|
||||||
"X-CSRFToken":CSRF,
|
"X-CSRFToken":CSRF,
|
||||||
@ -21,12 +21,12 @@ $(function () {
|
|||||||
// beforeSend: function(xhr) {
|
// beforeSend: function(xhr) {
|
||||||
// xhr.setRequestHeader("X-CSRFToken", csrf);
|
// xhr.setRequestHeader("X-CSRFToken", csrf);
|
||||||
// },
|
// },
|
||||||
success: function (response) {
|
success: function (data, textStatus, jqXHR) {
|
||||||
console.log(response.status);
|
console.log(jqXHR.status);
|
||||||
$(archiveListElement).hide(1500);
|
$(archiveListElement).hide(1500);
|
||||||
},
|
},
|
||||||
error: function (response) {
|
error: function (data, textStatus, jqXHR) {
|
||||||
console.log(response.status);
|
console.log(jqXHR.status);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -37,16 +37,13 @@ $(function () {
|
|||||||
let resolved = false;
|
let resolved = false;
|
||||||
let ticketStateUrl = $(this).attr("ticket-state-url")
|
let ticketStateUrl = $(this).attr("ticket-state-url")
|
||||||
if ($(this).attr("ticket-state-switch") === "1") {
|
if ($(this).attr("ticket-state-switch") === "1") {
|
||||||
console.log('Find it!!!')
|
|
||||||
resolved = true;
|
|
||||||
$(this).attr("ticket-state-switch", "0"); // disable
|
$(this).attr("ticket-state-switch", "0"); // disable
|
||||||
} else {
|
} else {
|
||||||
resolved = false;
|
resolved = true;
|
||||||
$(this).attr("ticket-state-switch", "1"); // enable
|
$(this).attr("ticket-state-switch", "1"); // enable
|
||||||
}
|
}
|
||||||
console.log(resolved)
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: "POST",
|
type: "PATCH",
|
||||||
url: ticketStateUrl,
|
url: ticketStateUrl,
|
||||||
headers: {
|
headers: {
|
||||||
"X-CSRFToken":CSRF,
|
"X-CSRFToken":CSRF,
|
||||||
@ -57,11 +54,12 @@ $(function () {
|
|||||||
data: JSON.stringify({
|
data: JSON.stringify({
|
||||||
resolved: resolved,
|
resolved: resolved,
|
||||||
}),
|
}),
|
||||||
success: function (response) {
|
success: function (data, textStatus, jqXHR) {
|
||||||
console.log(response.resolved)
|
console.log(jqXHR.status)
|
||||||
},
|
},
|
||||||
error: function (response) {
|
error: function (data, textStatus, jqXHR) {
|
||||||
console.log(response.resolved)
|
console.log(data)
|
||||||
|
console.log(jqXHR.status)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -80,16 +78,16 @@ $(function () {
|
|||||||
'X-CSRFToken':CSRF,
|
'X-CSRFToken':CSRF,
|
||||||
'Content-Type':'application/json'
|
'Content-Type':'application/json'
|
||||||
},
|
},
|
||||||
success: function (response) {
|
success: function (data, textStatus, jqXHR) {
|
||||||
console.log(response.status);
|
console.log(jqXHR.status);
|
||||||
if (delDiv.length) {
|
if (delDiv.length) {
|
||||||
delDiv.hide(1500);
|
delDiv.hide(1500);
|
||||||
} else {
|
} else {
|
||||||
window.location.href = redirectUrl;
|
window.location.href = redirectUrl;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error: function (response) {
|
error: function (data, textStatus, jqXHR) {
|
||||||
console.log(response.status);
|
console.log(jqXHR.status);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
>Cancel
|
>Cancel
|
||||||
</button>
|
</button>
|
||||||
<a
|
<a
|
||||||
href="{% url 'collector:download' archive.file %}"
|
href="{% url 'collector:archive-detail' archive.id %}"
|
||||||
type="button"
|
type="button"
|
||||||
class="btn btn-danger btn-archive-eraser"
|
class="btn btn-danger btn-archive-eraser"
|
||||||
data-bs-dismiss="modal"
|
data-bs-dismiss="modal"
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
</button>
|
</button>
|
||||||
<a
|
<a
|
||||||
type="button"
|
type="button"
|
||||||
href="{% url 'collector:ajax_delete_ticket' ticket.number %}"
|
href="{% url 'collector:ticket-detail' ticket.number %}"
|
||||||
class="btn btn-danger btn-ticket-del"
|
class="btn btn-danger btn-ticket-del"
|
||||||
data-bs-dismiss="modal"
|
data-bs-dismiss="modal"
|
||||||
data-jq-ticket-del-target="#div-ticket-{{ ticket.number }}"
|
data-jq-ticket-del-target="#div-ticket-{{ ticket.number }}"
|
||||||
|
@ -105,9 +105,13 @@
|
|||||||
{% if request.user.is_staff %}
|
{% if request.user.is_staff %}
|
||||||
<li>
|
<li>
|
||||||
<a class="dropdown-item" type="button" href="{% url 'admin:index' %}"
|
<a class="dropdown-item" type="button" href="{% url 'admin:index' %}"
|
||||||
><i class="bi bi-shield-shaded"></i></i> Admin</a>
|
><i class="bi bi-shield-shaded"></i> Admin</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
<li>
|
||||||
|
<a class="dropdown-item" type="button" href="{% url 'swagger-ui' %}"
|
||||||
|
><i class="bi bi-braces-asterisk"></i> Swagger</a>
|
||||||
|
</li>
|
||||||
<li><button class="dropdown-item" type="button"><i class="bi bi-gear"></i> Settings</button></li>
|
<li><button class="dropdown-item" type="button"><i class="bi bi-gear"></i> Settings</button></li>
|
||||||
<li><hr class="dropdown-divider" /></li>
|
<li><hr class="dropdown-divider" /></li>
|
||||||
<li><button class="dropdown-item" type="button"><i class="bi bi-door-closed"></i> Logout</button></li>
|
<li><button class="dropdown-item" type="button"><i class="bi bi-door-closed"></i> Logout</button></li>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
type="checkbox"
|
type="checkbox"
|
||||||
role="switch"
|
role="switch"
|
||||||
name="ticket-state"
|
name="ticket-state"
|
||||||
ticket-state-url="{% url 'collector:ajax_update_state_ticket' ticket.platform.name ticket.number %}"
|
ticket-state-url="{% url 'collector:ticket-detail' ticket.number %}"
|
||||||
{% if ticket.resolved %} ticket-state-switch="1" {% endif %}
|
{% if ticket.resolved %} ticket-state-switch="1" {% endif %}
|
||||||
{% if ticket.resolved %} checked {% endif %}>
|
{% if ticket.resolved %} checked {% endif %}>
|
||||||
</div>
|
</div>
|
||||||
|
@ -6,17 +6,11 @@ from . import views
|
|||||||
|
|
||||||
app_name = 'collector'
|
app_name = 'collector'
|
||||||
|
|
||||||
router = routers.DefaultRouter()
|
|
||||||
router.register(r'archives', views.ArchiveViewSet)
|
|
||||||
router.register(r'platforms', views.PlatformViewSet)
|
|
||||||
router.register(r'tickets', views.TicketViewSet)
|
|
||||||
|
|
||||||
urlpatterns = [
|
|
||||||
|
|
||||||
# █░█░█ █▀▀ █▄▄
|
# █░█░█ █▀▀ █▄▄
|
||||||
# ▀▄▀▄▀ ██▄ █▄█
|
# ▀▄▀▄▀ ██▄ █▄█
|
||||||
# -- -- -- -- --
|
# -- -- -- -- --
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
# CREATE:
|
# CREATE:
|
||||||
path(
|
path(
|
||||||
'tickets/create/',
|
'tickets/create/',
|
||||||
@ -55,28 +49,18 @@ urlpatterns = [
|
|||||||
views.UpdateTicket.as_view(),
|
views.UpdateTicket.as_view(),
|
||||||
name='update'
|
name='update'
|
||||||
),
|
),
|
||||||
|
]
|
||||||
# ▄▀█ ░░█ ▄▀█ ▀▄▀
|
|
||||||
# █▀█ █▄█ █▀█ █░█
|
|
||||||
# -- -- -- -- --
|
|
||||||
|
|
||||||
# UPDATE:
|
|
||||||
path(
|
|
||||||
'ajax/tickets/update/<slug:platform>/<int:ticket>/',
|
|
||||||
views.UpdateTicketStateHandler.as_view(),
|
|
||||||
name='ajax_update_state_ticket'
|
|
||||||
),
|
|
||||||
# DELETE:
|
|
||||||
path(
|
|
||||||
'ajax/tickets/delete/<int:ticket>/',
|
|
||||||
views.DeleteTicketHandler.as_view(),
|
|
||||||
name='ajax_delete_ticket'
|
|
||||||
),
|
|
||||||
|
|
||||||
# ▄▀█ █▀█ █
|
# ▄▀█ █▀█ █
|
||||||
# █▀█ █▀▀ █
|
# █▀█ █▀▀ █
|
||||||
# -- -- --
|
# -- -- --
|
||||||
|
|
||||||
|
router = routers.DefaultRouter()
|
||||||
|
router.register(r'archives', views.ArchiveViewSet)
|
||||||
|
router.register(r'platforms', views.PlatformViewSet)
|
||||||
|
router.register(r'tickets', views.TicketViewSet)
|
||||||
|
|
||||||
|
urlpatterns += [
|
||||||
# CRUD:
|
# CRUD:
|
||||||
path('api/v1/', include(router.urls)),
|
path('api/v1/', include(router.urls)),
|
||||||
]
|
]
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
import json
|
|
||||||
from django.core.exceptions import ValidationError, ObjectDoesNotExist
|
from django.core.exceptions import ValidationError, ObjectDoesNotExist
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
from django.http import FileResponse, JsonResponse
|
from django.http import FileResponse
|
||||||
from django.views import generic
|
from django.views import generic
|
||||||
from django.views.generic.detail import SingleObjectMixin
|
from django.views.generic.detail import SingleObjectMixin
|
||||||
from django.urls import reverse_lazy
|
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
@ -20,7 +18,7 @@ from django_filters.rest_framework import DjangoFilterBackend
|
|||||||
from .models import Archive, Ticket, Platform
|
from .models import Archive, Ticket, Platform
|
||||||
from .forms import TicketForm
|
from .forms import TicketForm
|
||||||
from .filters import ArchiveFilter, TicketFilter
|
from .filters import ArchiveFilter, TicketFilter
|
||||||
from .utils import PageTitleViewMixin, is_ajax
|
from .utils import PageTitleViewMixin
|
||||||
from .permissions import IsGuestUpload
|
from .permissions import IsGuestUpload
|
||||||
|
|
||||||
from .serializers import (
|
from .serializers import (
|
||||||
@ -40,12 +38,6 @@ class ArchiveHandlerView(LoginRequiredMixin, SingleObjectMixin, generic.View):
|
|||||||
self.object = self.get_object()
|
self.object = self.get_object()
|
||||||
return FileResponse(self.object.file)
|
return FileResponse(self.object.file)
|
||||||
|
|
||||||
def delete(self, request, path):
|
|
||||||
if is_ajax(request):
|
|
||||||
self.object = self.get_object()
|
|
||||||
self.object.delete()
|
|
||||||
return JsonResponse({'file': path}, status=status.HTTP_200_OK)
|
|
||||||
|
|
||||||
|
|
||||||
class CreateTicket(LoginRequiredMixin, PageTitleViewMixin, generic.CreateView):
|
class CreateTicket(LoginRequiredMixin, PageTitleViewMixin, generic.CreateView):
|
||||||
model = Ticket
|
model = Ticket
|
||||||
@ -71,7 +63,6 @@ class UpdateTicket(LoginRequiredMixin, PageTitleViewMixin, generic.UpdateView):
|
|||||||
return f'{self.title} - {self.kwargs.get("ticket", "update")}'
|
return f'{self.title} - {self.kwargs.get("ticket", "update")}'
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
print(self.request.user)
|
|
||||||
form.instance.user = self.request.user
|
form.instance.user = self.request.user
|
||||||
return super().form_valid(form)
|
return super().form_valid(form)
|
||||||
|
|
||||||
@ -95,13 +86,17 @@ class ListAllTickets(PageTitleViewMixin, generic.ListView):
|
|||||||
queryset = self.model.objects.filter(
|
queryset = self.model.objects.filter(
|
||||||
Q(number__in=query_list) | Q(number__icontains=query_list[0])
|
Q(number__in=query_list) | Q(number__icontains=query_list[0])
|
||||||
)
|
)
|
||||||
self.paginate_by = 100 # fake disable pagination)
|
self.paginate_by = 100 # ? fake disable pagination)
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
return super().get_queryset()
|
return super().get_queryset()
|
||||||
|
|
||||||
|
|
||||||
class ListPlatformTickets(PageTitleViewMixin, generic.ListView):
|
class ListPlatformTickets(
|
||||||
|
LoginRequiredMixin,
|
||||||
|
PageTitleViewMixin,
|
||||||
|
generic.ListView
|
||||||
|
):
|
||||||
model = Ticket
|
model = Ticket
|
||||||
template_name = 'collector/tickets.html'
|
template_name = 'collector/tickets.html'
|
||||||
context_object_name = 'tickets'
|
context_object_name = 'tickets'
|
||||||
@ -117,7 +112,7 @@ class ListPlatformTickets(PageTitleViewMixin, generic.ListView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class DetailTicket(PageTitleViewMixin, generic.DetailView):
|
class DetailTicket(LoginRequiredMixin, PageTitleViewMixin, generic.DetailView):
|
||||||
model = Ticket
|
model = Ticket
|
||||||
template_name = 'collector/ticket.html'
|
template_name = 'collector/ticket.html'
|
||||||
context_object_name = 'ticket'
|
context_object_name = 'ticket'
|
||||||
@ -128,62 +123,6 @@ class DetailTicket(PageTitleViewMixin, generic.DetailView):
|
|||||||
return f'{self.title} - {self.kwargs.get("ticket", "show")}'
|
return f'{self.title} - {self.kwargs.get("ticket", "show")}'
|
||||||
|
|
||||||
|
|
||||||
class DeleteTicket(PageTitleViewMixin, generic.DeleteView):
|
|
||||||
model = Ticket
|
|
||||||
template_name = 'collector/ticket_delete.html'
|
|
||||||
context_object_name = 'ticket'
|
|
||||||
slug_field = 'number'
|
|
||||||
slug_url_kwarg = 'ticket'
|
|
||||||
success_url = reverse_lazy('tickets')
|
|
||||||
|
|
||||||
|
|
||||||
class UpdateTicketStateHandler(SingleObjectMixin, generic.View):
|
|
||||||
model = Ticket
|
|
||||||
slug_field = 'number'
|
|
||||||
slug_url_kwarg = 'ticket'
|
|
||||||
|
|
||||||
def post(self, request, **kwargs):
|
|
||||||
if is_ajax(request):
|
|
||||||
self.object = self.get_object()
|
|
||||||
if request.body:
|
|
||||||
data = json.loads(request.body)
|
|
||||||
resolved_field = data.get('resolved')
|
|
||||||
if isinstance(resolved_field, bool):
|
|
||||||
self.object.resolved = not resolved_field
|
|
||||||
self.object.save()
|
|
||||||
return JsonResponse(
|
|
||||||
{'resolved': not resolved_field},
|
|
||||||
status=status.HTTP_201_CREATED
|
|
||||||
)
|
|
||||||
return JsonResponse(
|
|
||||||
{'resolved': 'must be a boolean'},
|
|
||||||
status=status.HTTP_400_BAD_REQUEST
|
|
||||||
)
|
|
||||||
return JsonResponse(
|
|
||||||
{'error': 'header XMLHttpRequest is required'},
|
|
||||||
status=status.HTTP_406_NOT_ACCEPTABLE
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class DeleteTicketHandler(SingleObjectMixin, generic.View):
|
|
||||||
model = Ticket
|
|
||||||
slug_field = 'number'
|
|
||||||
slug_url_kwarg = 'ticket'
|
|
||||||
|
|
||||||
def delete(self, request, ticket):
|
|
||||||
if is_ajax(request):
|
|
||||||
self.object = self.get_object()
|
|
||||||
self.object.delete()
|
|
||||||
return JsonResponse(
|
|
||||||
{'status': status.HTTP_200_OK},
|
|
||||||
status=status.HTTP_200_OK
|
|
||||||
)
|
|
||||||
return JsonResponse(
|
|
||||||
{'error': 'header XMLHttpRequest is required'},
|
|
||||||
status=status.HTTP_406_NOT_ACCEPTABLE
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class ArchiveViewSet(viewsets.ModelViewSet):
|
class ArchiveViewSet(viewsets.ModelViewSet):
|
||||||
queryset = Archive.objects.order_by('-time_create')
|
queryset = Archive.objects.order_by('-time_create')
|
||||||
serializer_class = ArchiveSerializer
|
serializer_class = ArchiveSerializer
|
||||||
@ -210,7 +149,7 @@ class ArchiveViewSet(viewsets.ModelViewSet):
|
|||||||
)
|
)
|
||||||
bound_ticket.attempts -= 1
|
bound_ticket.attempts -= 1
|
||||||
bound_ticket.save()
|
bound_ticket.save()
|
||||||
# ? mixin bound ticket to request.data from user
|
# ? mixin bound ticket number to request.data from user
|
||||||
request.data['ticket'] = bound_ticket.number
|
request.data['ticket'] = bound_ticket.number
|
||||||
# ? change serializer for guest user
|
# ? change serializer for guest user
|
||||||
self.serializer_class = PublicArchiveUploadSerializer
|
self.serializer_class = PublicArchiveUploadSerializer
|
||||||
|
@ -173,12 +173,6 @@ SPECTACULAR_SETTINGS = {
|
|||||||
'VERSION': '0.1.0',
|
'VERSION': '0.1.0',
|
||||||
'SERVE_INCLUDE_SCHEMA': True,
|
'SERVE_INCLUDE_SCHEMA': True,
|
||||||
'SERVE_PUBLIC': False,
|
'SERVE_PUBLIC': False,
|
||||||
'SERVERS': [
|
|
||||||
{
|
|
||||||
'url': 'http://localhost:8000/api/v1/',
|
|
||||||
'description': 'main api endpoint'
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# https://django-rest-framework-simplejwt.readthedocs.io/en/latest/
|
# https://django-rest-framework-simplejwt.readthedocs.io/en/latest/
|
||||||
|
Loading…
Reference in New Issue
Block a user