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_display = ('id', '__str__', 'advertisement')
|
||||||
list_filter = ('advertisement__url', 'source')
|
list_filter = ('advertisement__url', 'source')
|
||||||
date_hierarchy = 'created'
|
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.contenttypes.models import ContentType
|
||||||
from django.contrib.postgres.fields import JSONField
|
from django.contrib.postgres.fields import JSONField
|
||||||
from django.core.validators import EMPTY_VALUES
|
from django.core.validators import EMPTY_VALUES
|
||||||
|
from django.db import connections, connection
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from rest_framework import exceptions
|
||||||
|
|
||||||
from configuration.models import TranslationSettings
|
from configuration.models import TranslationSettings
|
||||||
from location.models import Country
|
from location.models import Country
|
||||||
from main import methods
|
from main import methods
|
||||||
from review.models import Review
|
from review.models import Review
|
||||||
|
from utils.exceptions import UnprocessableEntityError
|
||||||
|
from utils.methods import dictfetchall
|
||||||
from utils.models import (ProjectBaseMixin, TJSONField, URLImageMixin,
|
from utils.models import (ProjectBaseMixin, TJSONField, URLImageMixin,
|
||||||
TranslatedFieldsMixin, PlatformMixin)
|
TranslatedFieldsMixin, PlatformMixin)
|
||||||
|
|
||||||
|
|
@ -402,5 +406,85 @@ class Panel(ProjectBaseMixin):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
def execute_query(self):
|
def execute_query(self, request):
|
||||||
pass
|
"""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',
|
||||||
'user_id'
|
'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(),
|
path('page-types/', views.PageTypeListCreateView.as_view(),
|
||||||
name='page-types-list-create'),
|
name='page-types-list-create'),
|
||||||
path('panels/', views.PanelsListCreateView.as_view(), name='panels'),
|
path('panels/', views.PanelsListCreateView.as_view(), name='panels'),
|
||||||
path('panels/<int:pk>/', views.PanelsListCreateView.as_view(), name='panels-rud'),
|
path('panels/<int:pk>/', views.PanelsRUDView.as_view(), name='panels-rud'),
|
||||||
# path('panels/<int:pk>/execute/', views.PanelsView.as_view(), name='panels-execute')
|
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.contrib.contenttypes.models import ContentType
|
||||||
from django_filters.rest_framework import DjangoFilterBackend
|
from django_filters.rest_framework import DjangoFilterBackend
|
||||||
from rest_framework import generics, permissions
|
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 import serializers
|
||||||
from main.filters import AwardFilter
|
from main.filters import AwardFilter
|
||||||
from main.models import Award, Footer, PageType, Panel
|
from main.models import Award, Footer, PageType, Panel
|
||||||
from main.views import SiteSettingsView, SiteListView
|
from main.views import SiteSettingsView, SiteListView
|
||||||
|
from utils.pagination import TestPagination
|
||||||
|
|
||||||
|
|
||||||
class AwardLstView(generics.ListCreateAPIView):
|
class AwardLstView(generics.ListCreateAPIView):
|
||||||
|
|
@ -107,3 +110,15 @@ class PanelsRUDView(generics.RetrieveUpdateDestroyAPIView):
|
||||||
)
|
)
|
||||||
serializer_class = serializers.PanelSerializer
|
serializer_class = serializers.PanelSerializer
|
||||||
queryset = Panel.objects.all()
|
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
|
managed = False
|
||||||
db_table = 'ownership_affs'
|
db_table = 'ownership_affs'
|
||||||
|
|
||||||
|
|
||||||
class Panels(MigrateMixin):
|
class Panels(MigrateMixin):
|
||||||
using = 'legacy'
|
using = 'legacy'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -171,3 +171,11 @@ class RemovedBindingObjectNotFound(serializers.ValidationError):
|
||||||
"""The exception must be thrown if the object not found."""
|
"""The exception must be thrown if the object not found."""
|
||||||
|
|
||||||
default_detail = _('Removed binding 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
|
desc = cursor.description
|
||||||
nt_result = namedtuple('Result', [col[0] for col in desc])
|
nt_result = namedtuple('Result', [col[0] for col in desc])
|
||||||
return [nt_result(*row) for row in cursor.fetchall()]
|
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