Started the admin site

Can currently view all the questions and search through them
This commit is contained in:
Matthew Welch 2021-03-20 13:12:33 -07:00
parent 2d18b1b2bf
commit 197164d691
7 changed files with 200 additions and 3 deletions

61
admin/admin.py Normal file
View File

@ -0,0 +1,61 @@
import json
from flask import render_template, Blueprint, request, jsonify
import database
from database import get_all_questions, get_question
Admin = Blueprint("admin", __name__, template_folder="templates")
@Admin.route("/admin/")
def index():
return render_template("admin/index.html", title="admin")
@Admin.route("/admin/questions/")
def questions():
return render_template("admin/question_list.html")
@Admin.route("/admin/questions/edit/<int:question_id>")
def edit_question(question_id):
question: database.AllQuestions = get_question(database.AllQuestions, question_id)
return render_template("admin/edit_question.html", question=question)
@Admin.route("/admin/question_query")
def query_questions():
offset = request.args.get("offset", type=int)
limit = request.args.get("limit", type=int)
sort = request.args.get("sort")
order = request.args.get("order")
query = parse_question_query(request.args.get("filter"))
result = database.query_all_questions(offset, limit, query, sort, order)
response_dict = {
"total": result[1],
"rows": [],
}
for question in result[0]:
response_dict["rows"].append({
"id": question.question_id,
"question_id": question.question_id,
"question": question.question,
"answer": question.answer,
"multiple_choice": getattr(question, "multiple_choice", None) is not None,
"hidden_answer": getattr(question, "hidden_answer", None) is not None,
})
# question1 = get_question(database.AllQuestions, 0)
# question2 = get_question(database.AllQuestions, 1)
# question3 = get_question(database.AllQuestions, 2)
return jsonify(response_dict)
def parse_question_query(query):
if query:
query: dict = json.loads(query)
if "multiple_choice" in query.keys():
query["multiple_choice"] = True if query["multiple_choice"] == "true" else False
if "hidden_answer" in query.keys():
query["hidden_answer"] = True if query["hidden_answer"] == "true" else False
return query
return None

View File

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html class="h-100" lang="en">
<head>
<meta charset="UTF-8">
<title>Admin</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootswatch/4.5.2/cosmo/bootstrap.min.css">
{% block head %}{% endblock %}
</head>
<body class="d-flex flex-column h-100">
<nav class="navbar navbar-expand navbar-dark bg-primary">
<a class="navbar-brand" href="{{ url_for('admin.index') }}">Admin Site</a>
<button class="navbar-toggler" type="button">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="{{ url_for('admin.index') }}">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url_for('admin.questions') }}">Questions</a>
</li>
</ul>
</div>
</nav>
<div class="container">
{% block body %}{% endblock %}
</div>
<footer class="mt-auto py-3">
<div class="container text-center">
<span class="">Created By ItIsGood.com</span>
</div>
</footer>
</body>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js"></script>
{% block scripts %}{% endblock %}
</html>

View File

@ -0,0 +1,5 @@
{% extends "admin/base.html" %}
{% block body %}
<p>This is the admin home page</p>
{% endblock %}

View File

@ -0,0 +1,63 @@
{% extends "admin/base.html" %}
{% block head %}
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css">
<link rel="stylesheet" href="https://unpkg.com/bootstrap-table@1.18.2/dist/bootstrap-table.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.18.2/extensions/filter-control/bootstrap-table-filter-control.min.css">
{% endblock %}
{% block body %}
<table id="question-table" class="table"></table>
{% endblock %}
{% block scripts %}
<script src="https://unpkg.com/bootstrap-table@1.18.2/dist/bootstrap-table.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.18.2/extensions/filter-control/bootstrap-table-filter-control.min.js"></script>
<script>
function query_params(params) {
console.log(params);
return params;
}
var filter_data = [true, false]
$("#question-table").bootstrapTable({
url: "/admin/question_query",
pagination: true,
sidePagination: "server",
filterControl: true,
queryParams: query_params,
showRefresh: true,
searchOnEnterKey: true,
columns: [
{
field: "question_id",
title: "Question ID",
},
{
field: "question",
title: "Question",
filterControl: "input",
},
{
field: "answer",
title: "Answer",
filterControl: "input",
},
{
field: "multiple_choice",
title: "Has Multiple Choice",
filterControl: "select",
filterData: "var:filter_data",
},
{
field: "hidden_answer",
title: "Has Hidden Answer",
filterControl: "select",
filterData: "var:filter_data",
},
]
})
</script>
{% endblock %}

View File

@ -7,6 +7,7 @@ load_dotenv(".env")
class Config:
SECRET_KEY = environ.get("SECRET_KEY")
SECURITY_PASSWORD_SALT = environ.get("SECURITY_PASSWORD_SALT")
DB_USER = environ.get("DB_USER")
DB_PASSWORD = environ.get("DB_PASSWORD")
DB_HOST = environ.get("DB_HOST")

View File

@ -26,6 +26,9 @@ class AllQuestions(Base):
answer = Column(String)
addresses = Column(String)
multiple_choice = relationship("MultipleChoice", uselist=False, back_populates="all_question_relationship")
hidden_answer = relationship("HiddenAnswer", uselist=False, back_populates="all_question_relationship")
def __init__(self, question_id, question, answer, addresses):
self.question_id = question_id
self.question = question
@ -43,7 +46,7 @@ class HiddenAnswer(Base):
difficulty = Column(Integer)
hint = Column(JSON)
all_question_relationship = relationship("AllQuestions", foreign_keys=[question_id], lazy="joined", uselist=False)
all_question_relationship = relationship("AllQuestions", lazy="joined", back_populates="hidden_answer")
question = association_proxy("all_question_relationship", "question")
answer = association_proxy("all_question_relationship", "answer")
addresses = association_proxy("all_question_relationship", "addresses")
@ -66,7 +69,7 @@ class MultipleChoice(Base):
hint = Column(JSON)
wrong_answers = Column(ARRAY(String))
all_question_relationship = relationship("AllQuestions", foreign_keys=[question_id], lazy="joined", uselist=False)
all_question_relationship = relationship("AllQuestions", lazy="joined", back_populates="multiple_choice")
question = association_proxy("all_question_relationship", "question")
answer = association_proxy("all_question_relationship", "answer")
addresses = association_proxy("all_question_relationship", "addresses")
@ -118,7 +121,7 @@ def get_category_count(category: Union[Type[MultipleChoice], Type[HiddenAnswer],
return session.query(category).count()
def get_question(category: Union[Type[MultipleChoice], Type[HiddenAnswer], Type[AllQuestions]], question_id: int) -> Optional[Union[Type[MultipleChoice], Type[HiddenAnswer], Type[AllQuestions]]]:
def get_question(category: Union[Type[MultipleChoice], Type[HiddenAnswer], Type[AllQuestions]], question_id: int) -> Optional[Union[MultipleChoice, HiddenAnswer, AllQuestions]]:
session: sqlalchemy.orm.session.Session = Session()
return session.query(category).filter(category.question_id == question_id).one_or_none()
@ -149,3 +152,24 @@ def check_answer(question_id: int, guess: str) -> Tuple[bool, str]:
if question:
answer = question.answer
return answer == guess, answer
def query_all_questions(offset, limit, query: dict = None, sort=None, order=None) -> Tuple[List[AllQuestions], int]:
session: sqlalchemy.orm.session.Session = Session()
query_params = []
if query is not None:
for key in query.keys():
if key == "multiple_choice" or key == "hidden_answer":
if query[key]:
query_params.append(getattr(AllQuestions, key) != None)
else:
query_params.append(getattr(AllQuestions, key) == None)
else:
query_params.append(getattr(AllQuestions, key).ilike("%"+query[key]+"%"))
order_by = None
if sort and order:
order_by = getattr(getattr(AllQuestions, sort), order)()
q = session.query(AllQuestions).filter(*query_params).order_by(order_by)
questions = q.offset(offset).limit(limit).all()
count = q.count()
return questions, count

View File

@ -1,8 +1,11 @@
import os
from flask import Flask, render_template, request, jsonify
from flask_security import Security
import database
from admin import admin
app = Flask(__name__)
app.register_blueprint(admin.Admin)
environment_configuration = os.environ['CONFIGURATION_SETUP']
app.config.from_object(environment_configuration)