Skip to content

Commit 0b7bf7f

Browse files
committed
Dev : Future Updates
1 parent 1883b62 commit 0b7bf7f

File tree

23 files changed

+697
-363
lines changed

23 files changed

+697
-363
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ JsWeb is a minimalistic yet powerful Python web framework designed for developer
5656

5757
### Contributors
5858
<a href="https://github.com/jones-peter/jsweb/graphs/contributors">
59-
<img src="https://contrib.rocks/image?repo=jones-peter/jsweb" />
59+
<img src="https://contrib.rocks/image?repo=jones-peter/jsweb&v=2" />
6060
</a>
6161

6262
## Installation

jsweb/admin.py

Lines changed: 68 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
# jsweb/admin.py
22
import os
33
import logging
4+
from jinja2 import Environment, FileSystemLoader
5+
from jsweb import __VERSION__
46
from jsweb.blueprints import Blueprint
57
from jsweb.database import db_session
68
from jsweb.forms import Form, StringField
7-
from jsweb.response import redirect, url_for, render, HTMLResponse
9+
from jsweb.response import redirect, url_for, HTMLResponse
810
from jsweb.auth import admin_required, login_user
911
from sqlalchemy.inspection import inspect
1012

@@ -16,7 +18,10 @@ class Admin:
1618
"""
1719
def __init__(self, app=None):
1820
self.models = {}
19-
# Define the path to the admin's own static files
21+
22+
admin_template_dir = os.path.join(os.path.dirname(__file__), "admin_templates")
23+
self.jinja_env = Environment(loader=FileSystemLoader(admin_template_dir))
24+
2025
admin_static_folder = os.path.join(os.path.dirname(__file__), 'admin_static')
2126

2227
self.blueprint = Blueprint(
@@ -29,26 +34,41 @@ def __init__(self, app=None):
2934
if app:
3035
self.init_app(app)
3136

37+
def render(self, request, template_name, context=None):
38+
"""Renders a template using the admin's isolated Jinja2 environment."""
39+
if context is None:
40+
context = {}
41+
42+
context['request'] = request
43+
context['app'] = self.app
44+
context['admin_models'] = self.models.keys()
45+
context['url_for'] = lambda endpoint, **kwargs: url_for(request, endpoint, **kwargs)
46+
context['library_version'] = __VERSION__
47+
48+
if hasattr(request, 'csrf_token'):
49+
context['csrf_token'] = request.csrf_token
50+
51+
template = self.jinja_env.get_template(template_name)
52+
body = template.render(**context)
53+
return HTMLResponse(body)
54+
3255
def init_app(self, app):
3356
self.app = app
3457
self._register_dashboard_and_login()
3558
self.app.register_blueprint(self.blueprint)
3659

3760
def _register_dashboard_and_login(self):
3861
"""Registers the main admin dashboard and handles login."""
39-
def index(request):
62+
async def index(request):
4063
error = None
4164
if request.user and getattr(request.user, 'is_admin', False):
42-
context = {
43-
"admin_models": self.models.keys(),
44-
"request": request
45-
}
46-
return render(request, "dashboard.html", context=context)
65+
return self.render(request, "dashboard.html")
4766

4867
if request.method == "POST":
4968
from models import User
50-
username = request.form.get("username")
51-
password = request.form.get("password")
69+
form_data = await request.form()
70+
username = form_data.get("username")
71+
password = form_data.get("password")
5272

5373
user = User.query.filter_by(username=username).first()
5474

@@ -59,7 +79,7 @@ def index(request):
5979
else:
6080
error = "Invalid credentials or not an admin."
6181

62-
return render(request, "login.html", context={"error": error, "request": request})
82+
return self.render(request, "login.html", context={"error": error})
6383

6484
self.blueprint.add_route("/", index, endpoint="index", methods=["GET", "POST"])
6585

@@ -80,75 +100,71 @@ def register(self, model):
80100
pk_name = inspect(model).primary_key[0].name
81101

82102
@admin_required
83-
def list_view(request):
103+
async def list_view(request):
84104
records = db_session.query(model).all()
85105
columns = [c.name for c in model.__table__.columns]
86-
records_data = [r.to_dict() for r in records]
106+
records_data = [{c.name: getattr(r, c.name) for c in model.__table__.columns} for r in records]
107+
108+
AddForm = self._create_form_for_model(model)
109+
add_form = AddForm()
110+
87111
context = {
88112
"model_name": model_name,
89113
"columns": columns,
90114
"records": records_data,
91115
"pk_name": pk_name,
92-
"admin_models": self.models.keys(),
93-
"request": request
116+
"add_form": add_form
94117
}
95-
return render(request, "list.html", context=context)
118+
return self.render(request, "list.html", context=context)
96119

97120
@admin_required
98-
def add_view(request):
121+
async def add_view(request):
99122
ModelForm = self._create_form_for_model(model)
100-
form = ModelForm(formdata=request.form)
101-
if request.method == "POST" and form.validate():
123+
form_data = await request.form()
124+
form = ModelForm(formdata=form_data)
125+
126+
if form.validate():
102127
new_record = model()
103128
for field_name, field in form._fields.items():
104129
setattr(new_record, field_name, field.data)
105130
new_record.save()
106131
return redirect(url_for(request, f"admin.{model_name.lower()}_list"))
107132

133+
records = db_session.query(model).all()
134+
columns = [c.name for c in model.__table__.columns]
135+
records_data = [{c.name: getattr(r, c.name) for c in model.__table__.columns} for r in records]
108136
context = {
109137
"model_name": model_name,
110-
"form": form,
111-
"record": None,
112-
"admin_models": self.models.keys(),
113-
"request": request,
114-
"pk_name": pk_name
138+
"columns": columns,
139+
"records": records_data,
140+
"pk_name": pk_name,
141+
"add_form": form
115142
}
116-
117-
# If it's an AJAX request, render only the partial
118-
if request.headers.get("X-Requested-With") == "XMLHttpRequest":
119-
return render(request, "form_partial.html", context=context)
120-
121-
# Otherwise, render the full page
122-
return render(request, "form.html", context=context)
143+
return self.render(request, "list.html", context=context)
123144

124145
@admin_required
125-
def edit_view(request, **kwargs):
146+
async def edit_view(request, **kwargs):
126147
record_id = kwargs.get(pk_name)
127148
record = db_session.query(model).get(record_id)
149+
128150
ModelForm = self._create_form_for_model(model, instance=record)
129-
form = ModelForm(formdata=request.form)
130-
if request.method == "POST" and form.validate():
131-
for field_name, field in form._fields.items():
132-
setattr(record, field_name, field.data)
133-
record.save()
134-
return redirect(url_for(request, f"admin.{model_name.lower()}_list"))
135151

136-
context = {
137-
"model_name": model_name,
138-
"form": form,
139-
"record": record,
140-
"admin_models": self.models.keys(),
141-
"request": request,
142-
"pk_name": pk_name
143-
}
144-
145-
if request.headers.get("X-Requested-With") == "XMLHttpRequest":
146-
return render(request, "form_partial.html", context=context)
152+
if request.method == "POST":
153+
form_data = await request.form()
154+
form = ModelForm(formdata=form_data)
155+
if form.validate():
156+
for field_name, field in form._fields.items():
157+
setattr(record, field_name, field.data)
158+
record.save()
159+
return redirect(url_for(request, f"admin.{model_name.lower()}_list"))
160+
else:
161+
form = ModelForm()
147162

148-
return render(request, "form.html", context=context)
163+
context = {"model_name": model_name, "form": form, "record": record, "pk_name": pk_name}
164+
return self.render(request, "form.html", context=context)
149165

150166
@admin_required
151-
def delete_view(request, **kwargs):
167+
async def delete_view(request, **kwargs):
152168
if request.method == "POST":
153169
record_id = kwargs.get(pk_name)
154170
record = db_session.query(model).get(record_id)
@@ -157,6 +173,6 @@ def delete_view(request, **kwargs):
157173
return redirect(url_for(request, f"admin.{model_name.lower()}_list"))
158174

159175
self.blueprint.add_route(f"/{model_name.lower()}", list_view, endpoint=f"{model_name.lower()}_list")
160-
self.blueprint.add_route(f"/{model_name.lower()}/add", add_view, endpoint=f"{model_name.lower()}_add", methods=["GET", "POST"])
176+
self.blueprint.add_route(f"/{model_name.lower()}/add", add_view, endpoint=f"{model_name.lower()}_add", methods=["POST"])
161177
self.blueprint.add_route(f"/{model_name.lower()}/edit/<int:{pk_name}>", edit_view, endpoint=f"{model_name.lower()}_edit", methods=["GET", "POST"])
162178
self.blueprint.add_route(f"/{model_name.lower()}/delete/<int:{pk_name}>", delete_view, endpoint=f"{model_name.lower()}_delete", methods=["POST"])

0 commit comments

Comments
 (0)