Django
This commit is contained in:
0
apps/charts/__init__.py
Normal file
0
apps/charts/__init__.py
Normal file
3
apps/charts/admin.py
Normal file
3
apps/charts/admin.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
6
apps/charts/apps.py
Normal file
6
apps/charts/apps.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class ChartsConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'apps.charts'
|
||||
0
apps/charts/migrations/__init__.py
Normal file
0
apps/charts/migrations/__init__.py
Normal file
3
apps/charts/models.py
Normal file
3
apps/charts/models.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.db import models
|
||||
|
||||
# Create your models here.
|
||||
3
apps/charts/tests.py
Normal file
3
apps/charts/tests.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
7
apps/charts/urls.py
Normal file
7
apps/charts/urls.py
Normal file
@@ -0,0 +1,7 @@
|
||||
from django.urls import path
|
||||
|
||||
from apps.charts import views
|
||||
|
||||
urlpatterns = [
|
||||
path("", views.index, name="charts"),
|
||||
]
|
||||
13
apps/charts/views.py
Normal file
13
apps/charts/views.py
Normal file
@@ -0,0 +1,13 @@
|
||||
from django.shortcuts import render
|
||||
from django.core import serializers
|
||||
from apps.pages.models import *
|
||||
|
||||
# Create your views here.
|
||||
|
||||
def index(request):
|
||||
products = serializers.serialize('json', Product.objects.all())
|
||||
context = {
|
||||
'segment': 'charts',
|
||||
'products': products
|
||||
}
|
||||
return render(request, 'charts/index.html', context)
|
||||
5
apps/dyn_api/__init__.py
Normal file
5
apps/dyn_api/__init__.py
Normal file
@@ -0,0 +1,5 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
"""
|
||||
Copyright (c) 2019 - present AppSeed.us
|
||||
"""
|
||||
|
||||
8
apps/dyn_api/admin.py
Normal file
8
apps/dyn_api/admin.py
Normal file
@@ -0,0 +1,8 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
"""
|
||||
Copyright (c) 2019 - present AppSeed.us
|
||||
"""
|
||||
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
10
apps/dyn_api/apps.py
Normal file
10
apps/dyn_api/apps.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
"""
|
||||
Copyright (c) 2019 - present AppSeed.us
|
||||
"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
|
||||
class DynApiConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'apps.dyn_api'
|
||||
63
apps/dyn_api/helpers.py
Normal file
63
apps/dyn_api/helpers.py
Normal file
@@ -0,0 +1,63 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
"""
|
||||
Copyright (c) 2019 - present AppSeed.us
|
||||
"""
|
||||
|
||||
import datetime, sys, inspect, importlib
|
||||
|
||||
from functools import wraps
|
||||
|
||||
from django.db import models
|
||||
from django.http import HttpResponseRedirect, HttpResponse
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
class Utils:
|
||||
@staticmethod
|
||||
def get_class(config, name: str) -> models.Model:
|
||||
return Utils.model_name_to_class(config[name])
|
||||
|
||||
@staticmethod
|
||||
def get_manager(config, name: str) -> models.Manager:
|
||||
return Utils.get_class(config, name).objects
|
||||
|
||||
@staticmethod
|
||||
def get_serializer(config, name: str):
|
||||
class Serializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Utils.get_class(config, name)
|
||||
fields = '__all__'
|
||||
|
||||
return Serializer
|
||||
|
||||
@staticmethod
|
||||
def model_name_to_class(name: str):
|
||||
|
||||
model_name = name.split('.')[-1]
|
||||
model_import = name.replace('.'+model_name, '')
|
||||
|
||||
module = importlib.import_module(model_import)
|
||||
cls = getattr(module, model_name)
|
||||
|
||||
return cls
|
||||
|
||||
def check_permission(function):
|
||||
@wraps(function)
|
||||
def wrap(viewRequest, *args, **kwargs):
|
||||
|
||||
try:
|
||||
|
||||
# Check user
|
||||
if viewRequest.request.user.is_authenticated:
|
||||
|
||||
return function(viewRequest, *args, **kwargs)
|
||||
|
||||
# For authentication for guests
|
||||
return HttpResponseRedirect('/login/')
|
||||
|
||||
except Exception as e:
|
||||
|
||||
# On error
|
||||
return HttpResponse( 'Error: ' + str( e ) )
|
||||
|
||||
return wrap
|
||||
0
apps/dyn_api/migrations/__init__.py
Normal file
0
apps/dyn_api/migrations/__init__.py
Normal file
8
apps/dyn_api/tests.py
Normal file
8
apps/dyn_api/tests.py
Normal file
@@ -0,0 +1,8 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
"""
|
||||
Copyright (c) 2019 - present AppSeed.us
|
||||
"""
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
16
apps/dyn_api/urls.py
Normal file
16
apps/dyn_api/urls.py
Normal file
@@ -0,0 +1,16 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
"""
|
||||
Copyright (c) 2019 - present AppSeed.us
|
||||
"""
|
||||
|
||||
from django.contrib import admin
|
||||
from django.urls import path
|
||||
from apps.dyn_api import views
|
||||
|
||||
urlpatterns = [
|
||||
path('api/', views.index, name="dynamic_api"),
|
||||
|
||||
path('api/<str:model_name>/' , views.DynamicAPI.as_view(), name="model_api"),
|
||||
path('api/<str:model_name>/<str:id>' , views.DynamicAPI.as_view()),
|
||||
path('api/<str:model_name>/<str:id>/' , views.DynamicAPI.as_view()),
|
||||
]
|
||||
155
apps/dyn_api/views.py
Normal file
155
apps/dyn_api/views.py
Normal file
@@ -0,0 +1,155 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
"""
|
||||
Copyright (c) 2019 - present AppSeed.us
|
||||
"""
|
||||
|
||||
from django.http import Http404
|
||||
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.shortcuts import render, redirect, get_object_or_404
|
||||
|
||||
from rest_framework.generics import get_object_or_404
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.response import Response
|
||||
from django.http import HttpResponse
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
DYNAMIC_API = {}
|
||||
|
||||
try:
|
||||
DYNAMIC_API = getattr(settings, 'DYNAMIC_API')
|
||||
except:
|
||||
pass
|
||||
|
||||
from .helpers import Utils
|
||||
|
||||
def index(request):
|
||||
|
||||
context = {
|
||||
'routes' : settings.DYNAMIC_API.keys(),
|
||||
'segment': 'dynamic_api'
|
||||
}
|
||||
|
||||
return render(request, 'dyn_api/index.html', context)
|
||||
|
||||
class DynamicAPI(APIView):
|
||||
|
||||
# READ : GET api/model/id or api/model
|
||||
def get(self, request, **kwargs):
|
||||
|
||||
model_id = kwargs.get('id', None)
|
||||
try:
|
||||
if model_id is not None:
|
||||
|
||||
# Validate for integer
|
||||
try:
|
||||
model_id = int(model_id)
|
||||
|
||||
if model_id < 0:
|
||||
raise ValueError('Expect positive int')
|
||||
|
||||
except ValueError as e:
|
||||
return Response(data={
|
||||
'message': 'Input Error = ' + str(e),
|
||||
'success': False
|
||||
}, status=400)
|
||||
|
||||
thing = get_object_or_404(Utils.get_manager(DYNAMIC_API, kwargs.get('model_name')), id=model_id)
|
||||
model_serializer = Utils.get_serializer(DYNAMIC_API, kwargs.get('model_name'))(instance=thing)
|
||||
output = model_serializer.data
|
||||
else:
|
||||
all_things = Utils.get_manager(DYNAMIC_API, kwargs.get('model_name')).all()
|
||||
thing_serializer = Utils.get_serializer(DYNAMIC_API, kwargs.get('model_name'))
|
||||
output = []
|
||||
for thing in all_things:
|
||||
output.append(thing_serializer(instance=thing).data)
|
||||
except KeyError:
|
||||
return Response(data={
|
||||
'message': 'this model is not activated or not exist.',
|
||||
'success': False
|
||||
}, status=400)
|
||||
except Http404:
|
||||
return Response(data={
|
||||
'message': 'object with given id not found.',
|
||||
'success': False
|
||||
}, status=404)
|
||||
return Response(data={
|
||||
'data': output,
|
||||
'success': True
|
||||
}, status=200)
|
||||
|
||||
# CREATE : POST api/model/
|
||||
#@check_permission
|
||||
def post(self, request, **kwargs):
|
||||
try:
|
||||
model_serializer = Utils.get_serializer(DYNAMIC_API, kwargs.get('model_name'))(data=request.data)
|
||||
if model_serializer.is_valid():
|
||||
model_serializer.save()
|
||||
else:
|
||||
return Response(data={
|
||||
**model_serializer.errors,
|
||||
'success': False
|
||||
}, status=400)
|
||||
except KeyError:
|
||||
return Response(data={
|
||||
'message': 'this model is not activated or not exist.',
|
||||
'success': False
|
||||
}, status=400)
|
||||
return Response(data={
|
||||
'message': 'Record Created.',
|
||||
'success': True
|
||||
}, status=200)
|
||||
|
||||
# UPDATE : PUT api/model/id/
|
||||
#@check_permission
|
||||
def put(self, request, **kwargs):
|
||||
try:
|
||||
thing = get_object_or_404(Utils.get_manager(DYNAMIC_API, kwargs.get('model_name')), id=kwargs.get('id'))
|
||||
model_serializer = Utils.get_serializer(DYNAMIC_API, kwargs.get('model_name'))(instance=thing,
|
||||
data=request.data,
|
||||
partial=True)
|
||||
if model_serializer.is_valid():
|
||||
model_serializer.save()
|
||||
else:
|
||||
return Response(data={
|
||||
**model_serializer.errors,
|
||||
'success': False
|
||||
}, status=400)
|
||||
except KeyError:
|
||||
return Response(data={
|
||||
'message': 'this model is not activated or not exist.',
|
||||
'success': False
|
||||
}, status=400)
|
||||
except Http404:
|
||||
return Response(data={
|
||||
'message': 'object with given id not found.',
|
||||
'success': False
|
||||
}, status=404)
|
||||
return Response(data={
|
||||
'message': 'Record Updated.',
|
||||
'success': True
|
||||
}, status=200)
|
||||
|
||||
# DELETE : DELETE api/model/id/
|
||||
#@check_permission
|
||||
def delete(self, request, **kwargs):
|
||||
try:
|
||||
model_manager = Utils.get_manager(DYNAMIC_API, kwargs.get('model_name'))
|
||||
to_delete_id = kwargs.get('id')
|
||||
model_manager.get(id=to_delete_id).delete()
|
||||
except KeyError:
|
||||
return Response(data={
|
||||
'message': 'this model is not activated or not exist.',
|
||||
'success': False
|
||||
}, status=400)
|
||||
except Utils.get_class(DYNAMIC_API, kwargs.get('model_name')).DoesNotExist as e:
|
||||
return Response(data={
|
||||
'message': 'object with given id not found.',
|
||||
'success': False
|
||||
}, status=404)
|
||||
return Response(data={
|
||||
'message': 'Record Deleted.',
|
||||
'success': True
|
||||
}, status=200)
|
||||
0
apps/dyn_dt/.gitkeep
Normal file
0
apps/dyn_dt/.gitkeep
Normal file
0
apps/dyn_dt/__init__.py
Normal file
0
apps/dyn_dt/__init__.py
Normal file
8
apps/dyn_dt/admin.py
Normal file
8
apps/dyn_dt/admin.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from django.contrib import admin
|
||||
from .models import *
|
||||
|
||||
# Register your models here.
|
||||
|
||||
admin.site.register(PageItems)
|
||||
admin.site.register(HideShowFilter)
|
||||
admin.site.register(ModelFilter)
|
||||
5
apps/dyn_dt/apps.py
Normal file
5
apps/dyn_dt/apps.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
class DynDtConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'apps.dyn_dt'
|
||||
3
apps/dyn_dt/forms.py
Normal file
3
apps/dyn_dt/forms.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django import forms
|
||||
|
||||
# Create your forms here.
|
||||
63
apps/dyn_dt/migrations/0001_initial.py
Normal file
63
apps/dyn_dt/migrations/0001_initial.py
Normal file
@@ -0,0 +1,63 @@
|
||||
# Generated by Django 4.2.9 on 2025-03-30 11:44
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = []
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="HideShowFilter",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("parent", models.CharField(blank=True, max_length=255, null=True)),
|
||||
("key", models.CharField(max_length=255)),
|
||||
("value", models.BooleanField(default=False)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="ModelFilter",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("parent", models.CharField(blank=True, max_length=255, null=True)),
|
||||
("key", models.CharField(max_length=255)),
|
||||
("value", models.CharField(max_length=255)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="PageItems",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("parent", models.CharField(blank=True, max_length=255, null=True)),
|
||||
("items_per_page", models.IntegerField(default=25)),
|
||||
],
|
||||
),
|
||||
]
|
||||
0
apps/dyn_dt/migrations/__init__.py
Normal file
0
apps/dyn_dt/migrations/__init__.py
Normal file
24
apps/dyn_dt/models.py
Normal file
24
apps/dyn_dt/models.py
Normal file
@@ -0,0 +1,24 @@
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
# Create your models here.
|
||||
|
||||
class PageItems(models.Model):
|
||||
parent = models.CharField(max_length=255, null=True, blank=True)
|
||||
items_per_page = models.IntegerField(default=25)
|
||||
|
||||
class HideShowFilter(models.Model):
|
||||
parent = models.CharField(max_length=255, null=True, blank=True)
|
||||
key = models.CharField(max_length=255)
|
||||
value = models.BooleanField(default=False)
|
||||
|
||||
def __str__(self):
|
||||
return self.key
|
||||
|
||||
class ModelFilter(models.Model):
|
||||
parent = models.CharField(max_length=255, null=True, blank=True)
|
||||
key = models.CharField(max_length=255)
|
||||
value = models.CharField(max_length=255)
|
||||
|
||||
def __str__(self):
|
||||
return self.key
|
||||
0
apps/dyn_dt/templatetags/__init__.py
Normal file
0
apps/dyn_dt/templatetags/__init__.py
Normal file
22
apps/dyn_dt/templatetags/get_attribute.py
Normal file
22
apps/dyn_dt/templatetags/get_attribute.py
Normal file
@@ -0,0 +1,22 @@
|
||||
from django import template
|
||||
from datetime import datetime
|
||||
|
||||
register = template.Library()
|
||||
|
||||
|
||||
@register.filter(name="getattribute")
|
||||
def getattribute(value, arg):
|
||||
try:
|
||||
attr_value = getattr(value, arg)
|
||||
|
||||
if isinstance(attr_value, datetime):
|
||||
return attr_value.strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
return attr_value
|
||||
except:
|
||||
return ''
|
||||
|
||||
|
||||
@register.filter
|
||||
def get(dict_data, key):
|
||||
return dict_data.get(key, [])
|
||||
3
apps/dyn_dt/tests.py
Normal file
3
apps/dyn_dt/tests.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
18
apps/dyn_dt/urls.py
Normal file
18
apps/dyn_dt/urls.py
Normal file
@@ -0,0 +1,18 @@
|
||||
from django.urls import path
|
||||
from apps.dyn_dt import views
|
||||
|
||||
urlpatterns = [
|
||||
path('dynamic-dt/', views.index, name="dynamic_dt"),
|
||||
|
||||
path('create-filter/<str:model_name>/', views.create_filter, name="create_filter"),
|
||||
path('create-page-items/<str:model_name>/', views.create_page_items, name="create_page_items"),
|
||||
path('create-hide-show-items/<str:model_name>/', views.create_hide_show_filter, name="create_hide_show_filter"),
|
||||
path('delete-filter/<str:model_name>/<int:id>/', views.delete_filter, name="delete_filter"),
|
||||
path('create/<str:aPath>/', views.create, name="create"),
|
||||
path('delete/<str:aPath>/<int:id>/', views.delete, name="delete"),
|
||||
path('update/<str:aPath>/<int:id>/', views.update, name="update"),
|
||||
|
||||
path('export-csv/<str:aPath>/', views.ExportCSVView.as_view(), name='export_csv'),
|
||||
|
||||
path('dynamic-dt/<str:aPath>/', views.model_dt, name="model_dt"),
|
||||
]
|
||||
13
apps/dyn_dt/utils.py
Normal file
13
apps/dyn_dt/utils.py
Normal file
@@ -0,0 +1,13 @@
|
||||
from django.db.models import Q
|
||||
|
||||
def user_filter(request, queryset, fields, fk_fields=[]):
|
||||
value = request.GET.get('search')
|
||||
|
||||
if value:
|
||||
dynamic_q = Q()
|
||||
for field in fields:
|
||||
if field not in fk_fields:
|
||||
dynamic_q |= Q(**{f'{field}__icontains': value})
|
||||
return queryset.filter(dynamic_q)
|
||||
|
||||
return queryset
|
||||
315
apps/dyn_dt/views.py
Normal file
315
apps/dyn_dt/views.py
Normal file
@@ -0,0 +1,315 @@
|
||||
import requests, base64, json, csv
|
||||
from django.shortcuts import render, redirect, get_object_or_404
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.utils import timezone
|
||||
from django.http import HttpResponse, JsonResponse
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.conf import settings
|
||||
from django.urls import reverse
|
||||
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
|
||||
from django.urls import reverse
|
||||
from django.views import View
|
||||
from django.db import models
|
||||
from pprint import pp
|
||||
|
||||
from apps.dyn_dt.models import ModelFilter, PageItems, HideShowFilter
|
||||
from apps.dyn_dt.utils import user_filter
|
||||
|
||||
from cli import *
|
||||
|
||||
# Create your views here.
|
||||
|
||||
def index(request):
|
||||
|
||||
context = {
|
||||
'routes' : settings.DYNAMIC_DATATB.keys(),
|
||||
'segment': 'dynamic_dt'
|
||||
}
|
||||
|
||||
return render(request, 'dyn_dt/index.html', context)
|
||||
|
||||
def create_filter(request, model_name):
|
||||
model_name = model_name.lower()
|
||||
if request.method == "POST":
|
||||
keys = request.POST.getlist('key')
|
||||
values = request.POST.getlist('value')
|
||||
for i in range(len(keys)):
|
||||
key = keys[i]
|
||||
value = values[i]
|
||||
|
||||
ModelFilter.objects.update_or_create(
|
||||
parent=model_name,
|
||||
key=key,
|
||||
defaults={'value': value}
|
||||
)
|
||||
|
||||
return redirect(reverse('model_dt', args=[model_name]))
|
||||
|
||||
|
||||
def create_page_items(request, model_name):
|
||||
model_name = model_name.lower()
|
||||
if request.method == 'POST':
|
||||
items = request.POST.get('items')
|
||||
page_items, created = PageItems.objects.update_or_create(
|
||||
parent=model_name,
|
||||
defaults={'items_per_page':items}
|
||||
)
|
||||
return redirect(reverse('model_dt', args=[model_name]))
|
||||
|
||||
|
||||
def create_hide_show_filter(request, model_name):
|
||||
model_name = model_name.lower()
|
||||
if request.method == "POST":
|
||||
data_str = list(request.POST.keys())[0]
|
||||
data = json.loads(data_str)
|
||||
|
||||
HideShowFilter.objects.update_or_create(
|
||||
parent=model_name,
|
||||
key=data.get('key'),
|
||||
defaults={'value': data.get('value')}
|
||||
)
|
||||
|
||||
response_data = {'message': 'Model updated successfully'}
|
||||
return JsonResponse(response_data)
|
||||
|
||||
return JsonResponse({'error': 'Invalid request'}, status=400)
|
||||
|
||||
|
||||
def delete_filter(request, model_name, id):
|
||||
model_name = model_name.lower()
|
||||
filter_instance = ModelFilter.objects.get(id=id, parent=model_name)
|
||||
filter_instance.delete()
|
||||
return redirect(reverse('model_dt', args=[model_name]))
|
||||
|
||||
|
||||
def get_model_field_names(model, field_type):
|
||||
"""Returns a list of field names based on the given field type."""
|
||||
return [
|
||||
field.name for field in model._meta.get_fields()
|
||||
if isinstance(field, field_type)
|
||||
]
|
||||
|
||||
def model_dt(request, aPath):
|
||||
aModelName = None
|
||||
aModelClass = None
|
||||
choices_dict = {}
|
||||
|
||||
if aPath in settings.DYNAMIC_DATATB.keys():
|
||||
aModelName = settings.DYNAMIC_DATATB[aPath]
|
||||
aModelClass = name_to_class(aModelName)
|
||||
|
||||
if not aModelClass:
|
||||
return HttpResponse( ' > ERR: Getting ModelClass for path: ' + aPath )
|
||||
|
||||
#db_fields = [field.name for field in aModelClass._meta.get_fields() if not field.is_relation]
|
||||
db_fields = [field.name for field in aModelClass._meta.fields]
|
||||
fk_fields = get_model_fk_values(aModelClass)
|
||||
db_filters = []
|
||||
for f in db_fields:
|
||||
if f not in fk_fields.keys():
|
||||
db_filters.append( f )
|
||||
|
||||
for field in aModelClass._meta.fields:
|
||||
if field.choices:
|
||||
choices_dict[field.name] = field.choices
|
||||
|
||||
field_names = []
|
||||
for field_name in db_fields:
|
||||
fields, created = HideShowFilter.objects.get_or_create(key=field_name, parent=aPath.lower())
|
||||
if fields.key in db_fields:
|
||||
field_names.append(fields)
|
||||
|
||||
model_series = {}
|
||||
for f in db_fields:
|
||||
f_values = list ( aModelClass.objects.values_list( f, flat=True) )
|
||||
model_series[ f ] = ', '.join( str(i) for i in f_values)
|
||||
|
||||
# model filter
|
||||
filter_string = {}
|
||||
filter_instance = ModelFilter.objects.filter(parent=aPath.lower())
|
||||
for filter_data in filter_instance:
|
||||
if filter_data.key in db_fields:
|
||||
filter_string[f'{filter_data.key}__icontains'] = filter_data.value
|
||||
|
||||
order_by = request.GET.get('order_by', 'id')
|
||||
if order_by not in db_fields:
|
||||
order_by = 'id'
|
||||
|
||||
queryset = aModelClass.objects.filter(**filter_string).order_by(order_by)
|
||||
item_list = user_filter(request, queryset, db_fields, fk_fields.keys())
|
||||
|
||||
# pagination
|
||||
page_items = PageItems.objects.filter(parent=aPath.lower()).last()
|
||||
p_items = 25
|
||||
if page_items:
|
||||
p_items = page_items.items_per_page
|
||||
|
||||
page = request.GET.get('page', 1)
|
||||
paginator = Paginator(item_list, p_items)
|
||||
|
||||
try:
|
||||
items = paginator.page(page)
|
||||
except PageNotAnInteger:
|
||||
return redirect(reverse('model_dt', args=[aPath]))
|
||||
except EmptyPage:
|
||||
return redirect(reverse('model_dt', args=[aPath]))
|
||||
|
||||
read_only_fields = ('id', )
|
||||
|
||||
integer_fields = get_model_field_names(aModelClass, models.IntegerField)
|
||||
date_time_fields = get_model_field_names(aModelClass, models.DateTimeField)
|
||||
email_fields = get_model_field_names(aModelClass, models.EmailField)
|
||||
text_fields = get_model_field_names(aModelClass, (models.TextField, models.CharField))
|
||||
|
||||
context = {
|
||||
'page_title': 'Dynamic DataTable - ' + aPath.lower().title(),
|
||||
'link': aPath,
|
||||
'field_names': field_names,
|
||||
'db_field_names': db_fields,
|
||||
'db_filters': db_filters,
|
||||
'items': items,
|
||||
'page_items': p_items,
|
||||
'filter_instance': filter_instance,
|
||||
'read_only_fields': read_only_fields,
|
||||
|
||||
'integer_fields': integer_fields,
|
||||
'date_time_fields': date_time_fields,
|
||||
'email_fields': email_fields,
|
||||
'text_fields': text_fields,
|
||||
'fk_fields_keys': list( fk_fields.keys() ),
|
||||
'fk_fields': fk_fields ,
|
||||
'choices_dict': choices_dict,
|
||||
'segment': 'dynamic_dt'
|
||||
}
|
||||
return render(request, 'dyn_dt/model.html', context)
|
||||
|
||||
|
||||
@login_required(login_url='/accounts/login/')
|
||||
def create(request, aPath):
|
||||
aModelClass = None
|
||||
|
||||
if aPath in settings.DYNAMIC_DATATB.keys():
|
||||
aModelName = settings.DYNAMIC_DATATB[aPath]
|
||||
aModelClass = name_to_class(aModelName)
|
||||
|
||||
if not aModelClass:
|
||||
return HttpResponse( ' > ERR: Getting ModelClass for path: ' + aPath )
|
||||
|
||||
if request.method == 'POST':
|
||||
data = {}
|
||||
fk_fields = get_model_fk(aModelClass)
|
||||
|
||||
for attribute, value in request.POST.items():
|
||||
if attribute == 'csrfmiddlewaretoken':
|
||||
continue
|
||||
|
||||
# Process FKs
|
||||
if attribute in fk_fields.keys():
|
||||
value = name_to_class( fk_fields[attribute] ).objects.filter(id=value).first()
|
||||
|
||||
data[attribute] = value if value else ''
|
||||
|
||||
aModelClass.objects.create(**data)
|
||||
|
||||
return redirect(request.META.get('HTTP_REFERER'))
|
||||
|
||||
|
||||
@login_required(login_url='/accounts/login/')
|
||||
def delete(request, aPath, id):
|
||||
aModelClass = None
|
||||
|
||||
if aPath in settings.DYNAMIC_DATATB.keys():
|
||||
aModelName = settings.DYNAMIC_DATATB[aPath]
|
||||
aModelClass = name_to_class(aModelName)
|
||||
|
||||
if not aModelClass:
|
||||
return HttpResponse( ' > ERR: Getting ModelClass for path: ' + aPath )
|
||||
|
||||
item = aModelClass.objects.get(id=id)
|
||||
item.delete()
|
||||
return redirect(request.META.get('HTTP_REFERER'))
|
||||
|
||||
|
||||
@login_required(login_url='/accounts/login/')
|
||||
def update(request, aPath, id):
|
||||
aModelClass = None
|
||||
|
||||
if aPath in settings.DYNAMIC_DATATB.keys():
|
||||
aModelName = settings.DYNAMIC_DATATB[aPath]
|
||||
aModelClass = name_to_class(aModelName)
|
||||
|
||||
if not aModelClass:
|
||||
return HttpResponse( ' > ERR: Getting ModelClass for path: ' + aPath )
|
||||
|
||||
item = aModelClass.objects.get(id=id)
|
||||
fk_fields = get_model_fk(aModelClass)
|
||||
|
||||
if request.method == 'POST':
|
||||
for attribute, value in request.POST.items():
|
||||
|
||||
if attribute == 'csrfmiddlewaretoken':
|
||||
continue
|
||||
|
||||
if getattr(item, attribute, value) is not None:
|
||||
|
||||
# Process FKs
|
||||
if attribute in fk_fields.keys():
|
||||
value = name_to_class( fk_fields[attribute] ).objects.filter(id=value).first()
|
||||
|
||||
setattr(item, attribute, value)
|
||||
|
||||
item.save()
|
||||
|
||||
return redirect(request.META.get('HTTP_REFERER'))
|
||||
|
||||
|
||||
|
||||
# Export as CSV
|
||||
class ExportCSVView(View):
|
||||
def get(self, request, aPath):
|
||||
aModelName = None
|
||||
aModelClass = None
|
||||
|
||||
if aPath in settings.DYNAMIC_DATATB.keys():
|
||||
aModelName = settings.DYNAMIC_DATATB[aPath]
|
||||
aModelClass = name_to_class(aModelName)
|
||||
|
||||
if not aModelClass:
|
||||
return HttpResponse( ' > ERR: Getting ModelClass for path: ' + aPath )
|
||||
|
||||
db_field_names = [field.name for field in aModelClass._meta.get_fields()]
|
||||
fields = []
|
||||
show_fields = HideShowFilter.objects.filter(value=False, parent=aPath.lower())
|
||||
|
||||
for field in show_fields:
|
||||
if field.key in db_field_names:
|
||||
fields.append(field.key)
|
||||
else:
|
||||
print(f"Field {field.key} does not exist in {aModelClass} model.")
|
||||
|
||||
response = HttpResponse(content_type='text/csv')
|
||||
response['Content-Disposition'] = f'attachment; filename="{aPath.lower()}.csv"'
|
||||
|
||||
writer = csv.writer(response)
|
||||
writer.writerow(fields) # Write the header
|
||||
|
||||
filter_string = {}
|
||||
filter_instance = ModelFilter.objects.filter(parent=aPath.lower())
|
||||
for filter_data in filter_instance:
|
||||
filter_string[f'{filter_data.key}__icontains'] = filter_data.value
|
||||
|
||||
order_by = request.GET.get('order_by', 'id')
|
||||
queryset = aModelClass.objects.filter(**filter_string).order_by(order_by)
|
||||
|
||||
items = user_filter(request, queryset, db_field_names)
|
||||
|
||||
for item in items:
|
||||
row_data = []
|
||||
for field in fields:
|
||||
try:
|
||||
row_data.append(getattr(item, field))
|
||||
except AttributeError:
|
||||
row_data.append('')
|
||||
writer.writerow(row_data)
|
||||
|
||||
return response
|
||||
0
apps/pages/__init__.py
Normal file
0
apps/pages/__init__.py
Normal file
3
apps/pages/admin.py
Normal file
3
apps/pages/admin.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
6
apps/pages/apps.py
Normal file
6
apps/pages/apps.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class PagesConfig(AppConfig):
|
||||
default_auto_field = "django.db.models.BigAutoField"
|
||||
name = "apps.pages"
|
||||
23
apps/pages/migrations/0001_initial.py
Normal file
23
apps/pages/migrations/0001_initial.py
Normal file
@@ -0,0 +1,23 @@
|
||||
# Generated by Django 4.2.9 on 2025-04-06 16:19
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Product',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('name', models.CharField(max_length=100)),
|
||||
('info', models.CharField(default='', max_length=100)),
|
||||
('price', models.IntegerField(blank=True, null=True)),
|
||||
],
|
||||
),
|
||||
]
|
||||
0
apps/pages/migrations/__init__.py
Normal file
0
apps/pages/migrations/__init__.py
Normal file
12
apps/pages/models.py
Normal file
12
apps/pages/models.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from django.db import models
|
||||
|
||||
# Create your models here.
|
||||
|
||||
class Product(models.Model):
|
||||
id = models.AutoField(primary_key=True)
|
||||
name = models.CharField(max_length = 100)
|
||||
info = models.CharField(max_length = 100, default = '')
|
||||
price = models.IntegerField(blank=True, null=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
3
apps/pages/tests.py
Normal file
3
apps/pages/tests.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
7
apps/pages/urls.py
Normal file
7
apps/pages/urls.py
Normal file
@@ -0,0 +1,7 @@
|
||||
from django.urls import path
|
||||
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
path('', views.index, name='index'),
|
||||
]
|
||||
9
apps/pages/views.py
Normal file
9
apps/pages/views.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from django.shortcuts import render
|
||||
from django.http import HttpResponse
|
||||
|
||||
# Create your views here.
|
||||
|
||||
def index(request):
|
||||
|
||||
# Page from the theme
|
||||
return render(request, 'pages/index.html', {'segment': 'dashboard'})
|
||||
Reference in New Issue
Block a user