panels executor
This commit is contained in:
parent
6e72c7c0e4
commit
a1f06fd0b9
|
|
@ -54,3 +54,16 @@ class PageAdmin(admin.ModelAdmin):
|
|||
list_display = ('id', '__str__', 'advertisement')
|
||||
list_filter = ('advertisement__url', 'source')
|
||||
date_hierarchy = 'created'
|
||||
|
||||
|
||||
@admin.register(models.Footer)
|
||||
class FooterAdmin(admin.ModelAdmin):
|
||||
"""Footer admin."""
|
||||
list_display = ('id', 'site', )
|
||||
|
||||
|
||||
@admin.register(models.Panel)
|
||||
class PanelAdmin(admin.ModelAdmin):
|
||||
"""Panel admin."""
|
||||
list_display = ('id', 'created', )
|
||||
raw_id_fields = ('user', )
|
||||
|
|
@ -6,14 +6,18 @@ from django.contrib.contenttypes import fields as generic
|
|||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.contrib.postgres.fields import JSONField
|
||||
from django.core.validators import EMPTY_VALUES
|
||||
from django.db import connections, connection
|
||||
from django.db import models
|
||||
from django.db.models import Q
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import exceptions
|
||||
|
||||
from configuration.models import TranslationSettings
|
||||
from location.models import Country
|
||||
from main import methods
|
||||
from review.models import Review
|
||||
from utils.exceptions import UnprocessableEntityError
|
||||
from utils.methods import dictfetchall
|
||||
from utils.models import (ProjectBaseMixin, TJSONField, URLImageMixin,
|
||||
TranslatedFieldsMixin, PlatformMixin)
|
||||
|
||||
|
|
@ -402,5 +406,85 @@ class Panel(ProjectBaseMixin):
|
|||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def execute_query(self):
|
||||
pass
|
||||
def execute_query(self, request):
|
||||
"""Execute query"""
|
||||
raw = self.query
|
||||
page = int(request.query_params.get('page', 0))
|
||||
page_size = int(request.query_params.get('page_size', 10))
|
||||
|
||||
if raw:
|
||||
data = {
|
||||
"count": 0,
|
||||
"next": 2,
|
||||
"previous": None,
|
||||
"columns": None,
|
||||
"results": []
|
||||
|
||||
}
|
||||
with connections['default'].cursor() as cursor:
|
||||
count = self._raw_count(raw)
|
||||
start = page*page_size
|
||||
cursor.execute(*self.set_limits(start, page_size))
|
||||
data["count"] = count
|
||||
data["next"] = self.get_next_page(count, page, page_size)
|
||||
data["previous"] = self.get_previous_page(count, page)
|
||||
data["results"] = dictfetchall(cursor)
|
||||
data["columns"] = self._raw_columns(cursor)
|
||||
return data
|
||||
|
||||
def get_next_page(self, count, page, page_size):
|
||||
max_page = count/page_size-1
|
||||
if not 0 <= page <= max_page:
|
||||
raise exceptions.NotFound('Invalid page.')
|
||||
if max_page > page:
|
||||
return page + 1
|
||||
return None
|
||||
|
||||
def get_previous_page(self, count, page):
|
||||
if page > 0:
|
||||
return page - 1
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def _raw_execute(row):
|
||||
with connections['default'].cursor() as cursor:
|
||||
try:
|
||||
cursor.execute(row)
|
||||
return cursor.execute(row)
|
||||
except Exception as er:
|
||||
# TODO: log
|
||||
raise UnprocessableEntityError()
|
||||
|
||||
def _raw_count(self, subquery):
|
||||
if ';' in subquery:
|
||||
subquery = subquery.replace(';', '')
|
||||
_count_query = f"""SELECT count(*) from ({subquery}) as t;"""
|
||||
# cursor = self._raw_execute(_count_query)
|
||||
with connections['default'].cursor() as cursor:
|
||||
cursor.execute(_count_query)
|
||||
row = cursor.fetchone()
|
||||
return row[0]
|
||||
|
||||
@staticmethod
|
||||
def _raw_columns(cursor):
|
||||
columns = [col[0] for col in cursor.description]
|
||||
return columns
|
||||
|
||||
def _raw_page(self, raw, request):
|
||||
page = request.query_params.get('page', 0)
|
||||
page_size = request.query_params.get('page_size', 0)
|
||||
raw = f"""{raw} LIMIT {page_size} OFFSET {page}"""
|
||||
return raw
|
||||
|
||||
def set_limits(self, start, limit, params=tuple()):
|
||||
limit_offset = ''
|
||||
new_params = tuple()
|
||||
if start > 0:
|
||||
new_params += (start,)
|
||||
limit_offset = ' OFFSET %s'
|
||||
if limit is not None:
|
||||
new_params = (limit,) + new_params
|
||||
limit_offset = ' LIMIT %s' + limit_offset
|
||||
params = params + new_params
|
||||
query = self.query + limit_offset
|
||||
return query, params
|
||||
|
|
|
|||
|
|
@ -296,3 +296,20 @@ class PanelSerializer(serializers.ModelSerializer):
|
|||
'user',
|
||||
'user_id'
|
||||
]
|
||||
|
||||
|
||||
class PanelExecuteSerializer(serializers.ModelSerializer):
|
||||
"""Panel execute serializer."""
|
||||
class Meta:
|
||||
model = models.Panel
|
||||
fields = [
|
||||
'id',
|
||||
'name',
|
||||
'display',
|
||||
'description',
|
||||
'query',
|
||||
'created',
|
||||
'modified',
|
||||
'user',
|
||||
'user_id'
|
||||
]
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ urlpatterns = [
|
|||
path('page-types/', views.PageTypeListCreateView.as_view(),
|
||||
name='page-types-list-create'),
|
||||
path('panels/', views.PanelsListCreateView.as_view(), name='panels'),
|
||||
path('panels/<int:pk>/', views.PanelsListCreateView.as_view(), name='panels-rud'),
|
||||
# path('panels/<int:pk>/execute/', views.PanelsView.as_view(), name='panels-execute')
|
||||
path('panels/<int:pk>/', views.PanelsRUDView.as_view(), name='panels-rud'),
|
||||
path('panels/<int:pk>/execute/', views.PanelsExecuteView.as_view(), name='panels-execute')
|
||||
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
from django.contrib.contenttypes.models import ContentType
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
from rest_framework import generics, permissions
|
||||
from rest_framework.generics import get_object_or_404
|
||||
from rest_framework.response import Response
|
||||
|
||||
from main import serializers
|
||||
from main.filters import AwardFilter
|
||||
from main.models import Award, Footer, PageType, Panel
|
||||
from main.views import SiteSettingsView, SiteListView
|
||||
from utils.pagination import TestPagination
|
||||
|
||||
|
||||
class AwardLstView(generics.ListCreateAPIView):
|
||||
|
|
@ -107,3 +110,15 @@ class PanelsRUDView(generics.RetrieveUpdateDestroyAPIView):
|
|||
)
|
||||
serializer_class = serializers.PanelSerializer
|
||||
queryset = Panel.objects.all()
|
||||
|
||||
|
||||
class PanelsExecuteView(generics.ListAPIView):
|
||||
"""Custom panels view."""
|
||||
permission_classes = (
|
||||
permissions.IsAdminUser,
|
||||
)
|
||||
queryset = Panel.objects.all()
|
||||
|
||||
def list(self, request, *args, **kwargs):
|
||||
panel = get_object_or_404(Panel, id=self.kwargs['pk'])
|
||||
return Response(panel.execute_query(request))
|
||||
|
|
|
|||
|
|
@ -1239,6 +1239,7 @@ class OwnershipAffs(MigrateMixin):
|
|||
managed = False
|
||||
db_table = 'ownership_affs'
|
||||
|
||||
|
||||
class Panels(MigrateMixin):
|
||||
using = 'legacy'
|
||||
|
||||
|
|
|
|||
|
|
@ -171,3 +171,11 @@ class RemovedBindingObjectNotFound(serializers.ValidationError):
|
|||
"""The exception must be thrown if the object not found."""
|
||||
|
||||
default_detail = _('Removed binding object not found.')
|
||||
|
||||
|
||||
class UnprocessableEntityError(exceptions.APIException):
|
||||
"""
|
||||
The exception should be thrown when executing data on server rise error.
|
||||
"""
|
||||
status_code = status.HTTP_422_UNPROCESSABLE_ENTITY
|
||||
default_detail = _('Unprocessable entity valid.')
|
||||
|
|
|
|||
|
|
@ -132,3 +132,12 @@ def namedtuplefetchall(cursor):
|
|||
desc = cursor.description
|
||||
nt_result = namedtuple('Result', [col[0] for col in desc])
|
||||
return [nt_result(*row) for row in cursor.fetchall()]
|
||||
|
||||
|
||||
def dictfetchall(cursor):
|
||||
"Return all rows from a cursor as a dict"
|
||||
columns = [col[0] for col in cursor.description]
|
||||
return [
|
||||
dict(zip(columns, row))
|
||||
for row in cursor.fetchall()
|
||||
]
|
||||
Loading…
Reference in New Issue
Block a user