В этой статье мы собираемся исследовать создание приложения викторины, используя веб-каркас Python Django и Fauna. Если это ваш первый раз, услышав о фауне, пожалуйста, посетите мою предыдущую статью здесь для краткого введения.
Первый шаг, который мы собираемся взять, это создать новую базу данных в фауне. Чтобы создать базу данных фауны, вы должны сначала зарегистрироваться для счета . Если вы этого не сделали. После регистрации вы можете создать новую базу данных, нажав на Создать базу данных
Кнопка на приборной панели.
После нажатия на кнопку, как показано на рисунке выше, вам нужно дать базу данных имени и сохранить его. Для этого учебника мы собираемся назвать нашу базу данных Викторина
Отказ
Вам также нужно будет создать четыре коллекции (один для Пользователи
, Викторина
, Вопрос:| и
Ответы ). Коллекция может рассматриваться как таблица в системе базы данных. Нажмите на
Создать коллекцию Затем заполните необходимые поля. Вам нужно будет ввести имя для коллекции,
История дней и
Ттл .
История дней Сколько дней вы хотите, чтобы «Фауна» сохранить историческую запись любых данных в этой коллекции, пока
TTL Является ли дата истечения срока действия данных в коллекции. Например, если
TTL Установлено на 5, любые данные, хранящиеся в коллекции, будут автоматически удалены через 5 дней после последней модифицированной даты.
Нам нужно будет создать восемь (8) индексов из фауны, которые позволят нам прокрутить данные, добавленные в нашу базу данных. Индексы являются; Пользователь
, Quiz_index
, Quiz_get_index
, Вопрос_index
, Вопрос_get_index
, Вопрос_answer
, answer_score_index
и answer_get_index
Отказ Пользователь
Указатель будет иметь термин для «имени пользователя» и будет уникальным полем, которое позволит запросу Пользователь
коллекция. Quiz_index
Указатель будет иметь термин для «имени» и будет уникальным полем, которое позволит запросу и создание новых документов в Викторина
коллекция. Quiz_get_index
Индекс будет иметь термин для «статуса», который также позволит запросу Викторина
коллекция. Вопрос_index
Индекс будет иметь термин для «вопроса_asked», который позволит запросу Вопрос:| коллекция.
Вопрос_get_index будет иметь термин для «имя», который позволит запросу и соответствие с данными в
Вопрос:| коллекция. Вопрос_answer
Указатель будет иметь термин для «revent_answer», который также позволит запросу и сопоставление Вопрос:| коллекция.
answer_score_index будет иметь термин для «пользователя» и «викторина», который позволит сопоставить и запросу
Ответы коллекция.
answer_get_index будет иметь срок для «пользователей» и «вопрос», который также позволит соответствовать и запросу
Ответы коллекция.
Прежде чем вы сможете начать создание приложения Django, которое использует фауну, вам необходимо создать ключ API, который позволит нашему приложению Django легко взаимодействовать с базой данных. Чтобы создать ключ API, перейдите на вкладку «Безопасность» на левой стороне экрана.
Нажмите Новый ключ
генерировать ключ. Затем вы должны предоставить базу данных для подключения ключа к роли ключа и необязательное имя для вашей клавиши API. После предоставления необходимой информации нажмите « » Сохранить
кнопка.
После сохранения вашего ключа ваш секретный ключ будет представлен как на изображении выше (скрыто здесь для конфиденциальности). Скопируйте свой секретный ключ от приборной панели и сохраните его где-то, вы можете легко получить его для последующего использования.
Предварительные условия
С этой точки зрения, чтобы следить за этим пошаговым руководством по созданию приложения Quiz с Django, вам необходимо установить следующее:
- Python 3.7 или> 3.7
- Фаунадб
- Django
Установка требований
Чтобы установить Fauna и Django, вам просто нужно запустить команду ниже в вашем интерфейсе командной строки.
pip install faunadb
Создание проекта Django
Чтобы создать проект Django, вам необходимо запустить команду ниже в интерфейсе командной строки.
#creating the django project django-admin startproject Quiz #changing directory to the django project cd Quiz #creating a django app django-admin startapp App
Вышеуказанная команда сначала создает проект Викторина
Затем изменяет каталог в проект. В каталоге проекта последняя команда создает новое приложение, называемое Приложение
Отказ
Структура проекта Django
Проект Django должен быть структурирован определенным образом, который следует правилам Django, и нам легко работать. Перейдите к Приложение
Папка в вашем проекте, затем создать новый файл Urls.py.
. Далее, в Приложение
Папка создает две новые папки Шаблоны
и статический
Отказ Папка шаблона будет размещать наши HTML-файлы, а статическая папка будет размещать наши CSS, JavaScript и другие статические файлы. Для этого запустите команду ниже на вашей командной строке.
# changing directory to our app cd App # creating the static and templates folders mkdir templates mkdir static
Папка «Приложение» теперь должна выглядеть как изображение ниже.
Теперь вернитесь к нашему Викторина
каталог и редактировать наши settings.py
Файл, добавив наше приложение в список установленных приложений, как видно ниже.
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'App', ]
Внутри статический
и Шаблоны
Папки, мы собираемся создавать свои соответствующие файлы.
Для Шаблоны
Папка Создайте новый файл Dashboard.html
и добавьте HTML-код ниже.
{% load static %}QUIZ APP Welcome {{user}}
Это Dashboard.html
Файл – это страница приборной панели, где пользователь может легко перемещаться между функциями сайта.
Далее создайте login.html
Файл, редактировать и добавить следующий HTML-код, как показано ниже.
{% load static %}QUIZ APP
login.html
Страница – это страница, в которой пользователи могут быть легко аутентифицированы до доступа к функциям сайта. Пользователи обязаны вводить их имя пользователя и пароль для входа в систему.
Следующая страница, которую мы собираемся создавать, это страница регистров.
Создайте новый файл Register.html
, отредактируйте и добавьте HTML-код, как показано ниже.
{% load static %}QUIZ APP Create Account
Register.html
Страница – это то, где пользователи могут создавать новые учетные записи для использования для аутентификации входа в систему. Пользователи обязаны ввести свое имя пользователя, электронную почту и пароль.
Следующая страница – это Quiz.html
Страница, в которой пользователи могут видеть все созданные викторины. Создать Quiz.html
Файл и добавьте код ниже.
{% load static %}QUIZ APP There {% if count == 1 %} is {{count}} quiz {% else %} are {{count}} quizes {% endif %} available
Choose a Quiz To Take
{{quiz.name}}
Следующая страница, которую мы собираемся создавать, это create_quiz.html
Страница, где пользователи могут создавать новые викторины для пользователей, чтобы ответить. Создать create_quiz.html
Страница и добавьте код ниже.
{% load static %}QUIZ APP Create a Quiz
Нам также нужно создать answer_quiz.html
Страница, где пользователи могут ответить на викторину, которую они выбрали на Quiz.html.
Страница, которую мы создали ранее. Скопируйте и вставьте код ниже в вашем answer_quiz.html
файл.
{% load static %}QUIZ APP Choose Any Option from A to D
SCIENCE TEST {% if messages %} {% endif %} {% if score %}
Total Score: {{score}} out of {{question_count}}
{% else %} {% if finish %} {% endif %} {% endif %} Back
Окончательная страница – это create_questions.html.
Страница, в которой пользователь может создавать вопросы, которые появятся под виктором. Создать копию и вставьте код ниже.
{% load static %}QUIZ APP Create a Question
Мы закончили создание необходимых файлов HTML. Теперь нам нужно создать наши файлы CSS. Перейдите к статический
Папка, создайте новую папку в нем; Вход
папка.
В Вход
Папка, создайте новый файл style.csss
и добавьте код CSS, как видно в Github Gist Link здесь Отказ
Мы сделаем с статический
и Шаблоны
папки. Давайте теперь отредактируем URLS.PY
и Просмотр .py
файл. В URLS.PY
Файл, скопируйте и добавьте следующий код Python, как показано ниже.
from django.conf import settings from django.conf.urls.static import static from django.urls import path, include from . import views app_name = "App" urlpatterns = [ path("", views.login, name="login"), path("login", views.login, name="login"), path("dashboard", views.dashboard, name="dashboard"), path("quiz", views.quiz, name="quiz"), path("register", views.register, name="register"), path("create-quiz", views.create_quiz, name="create-quiz"), path("create-questions", views.create_question, name="create-question"), path("answer-quiz/", views.answer_quiz, name="answer-quiz"), ]
В URLS.PY
Файл, который мы импортировали необходимые модули Django, необходимые и определили все URL-адреса, мы собираемся использовать в этом проекте, и подключили их с необходимой функцией просмотра, необходимой для них.
from django.shortcuts import render,redirect from django.contrib import messages from django.core.paginator import Paginator from django.http import HttpResponseNotFound from faunadb import query as q import pytz from faunadb.objects import Ref from faunadb.client import FaunaClient import hashlib import datetime client = FaunaClient(secret="SECRET_KEY") indexes = client.query(q.paginate(q.indexes()))
В Просмотр .py
Файл, который мы импортировали все необходимые модули Django и инициализировали клиента Fauna, используя наш секретный ключ, который мы сохранили ранее.
Перейдите к базовому каталогу и откройте Викторина
Папка, как видно на изображении ниже.
from django.contrib import admin from django.urls import path, include from django.conf import settings from django.contrib.staticfiles.urls import staticfiles_urlpatterns from django.contrib.staticfiles.urls import static urlpatterns = [ path('admin/', admin.site.urls), path('', include("App.urls")), ]
В базовом проекте URLS.PY
Мы импортировали необходимые модули и связали URL-адрес приложения на наши URL-адреса базового пути.
Мы будем проходить все шаги для создания функциональности нашего приложения викторины.
Функциональность регистрации
Первое действие, которое пользователь принимает при открытии веб-приложения, – это зарегистрироваться, если у них еще нет. Обновите функцию регистра в Просмотр .py
с кодом Python ниже.
def register(request): if request.method == "POST": username = request.POST.get("username").strip().lower() email = request.POST.get("email").strip().lower() password = request.POST.get("password") try: user = client.query(q.get(q.match(q.index("users_index"), username))) messages.add_message(request, messages.INFO, 'User already exists with that username.') return redirect("App:register") except: user = client.query(q.create(q.collection("users"), { "data": { "username": username, "email": email, "password": hashlib.sha512(password.encode()).hexdigest(), "date": datetime.datetime.now(pytz.UTC) } })) messages.add_message(request, messages.INFO, 'Registration successful.') return redirect("App:login") return render(request,"register.html")
В Регистрация
Просмотр функции, мы впервые проверили, отправлена ли запрос на странице «Регистрация» – это запрос на почту, который мы просто визуализируем страницу регистра. Если это было так, то мы должны ожидать некоторых значений (i.e имя пользователя, электронное письмо и пароль) в запросе пост. Затем мы просим к фауне с Получить
Метод клиента FQL и users_index
Ранее мы создали ранее, чтобы проверить коллекцию пользователя, если пользователь с совпадением имени пользователя уже существует. Если пользователь существует, то отображается сообщение «Пользователь с этим именем пользователя». Если пользователь не существует, запрос выполнен с клиентом FQL в FQUUNA для создания документа с предоставленными деталями вместе с датой регистрации. Пользователь теперь перенаправляется на страницу входа в систему, чтобы войти с его/ее недавно созданными входами в систему. Если вы проверяете Пользователи
Коллекция Вы должны увидеть данные, добавленные ниже.
На неудачной регистрации следует отобразить сообщение, как видно на изображении ниже.
Функциональность входа в систему
Второе действие Пользователь берет, когда он открывает веб-приложение, – предоставить свои данные входа в систему для аутентификации. Обновите функцию входа в Просмотр .py
С следующим кодом Python для реализации функциональности входа в систему.
def login(request): if request.method == "POST": username = request.POST.get("username").strip().lower() password = request.POST.get("password") try: user = client.query(q.get(q.match(q.index("users_index"), username))) if hashlib.sha512(password.encode()).hexdigest() == user["data"]["password"]: request.session["user"] = { "id": user["ref"].id(), "username": user["data"]["username"] } return redirect("App:dashboard") else: raise Exception() except: messages.add_message(request, messages.INFO,"You have supplied invalid login credentials, please try again!", "danger") return redirect("App:login") return render(request,"login.html")
В Вход
Функция представлений, мы сначала проверяем, отправлена ли запрос на странице входа в систему, это запрос на почту, который просто мы просто визуализируем страницу входа. Если это было так, то мы должны ожидать некоторых значений (i.e имя пользователя и пароль) в запросе пост. После сбора имени пользователя и пароля мы тогда используем Получить
Метод клиента FQL и users_index
Ранее мы создали запрос на Fauna, чтобы проверить, существует ли пользователь, используя имя пользователя в качестве совпадения. Если этот пользователь существует, мы тогда проверяем, пройдете ли пароль правильный, перемешивая его и сравнивая его с хешированным паролем на фауне. Если пароль правильный, мы храним данные пользователя на сеансе и перенаправьте его/ее на приборную панель. Если пользователь не существует или пароль не совпадает, то мы передаем сообщение «Вы предоставили неверные учетные данные входа в систему на странице входа в систему, затем перенаправьте пользователя обратно на страницу входа. Затем мы кэшировали нашу функцию с помощью попытки справиться с любыми ошибками, которые могут прийти от запроса фауны.
Если логин был неудачным, вы должны получить результат, как видно на изображении ниже.
Приборная панель
Обновите свой Просмотр .py
Файл с кодом ниже, чтобы создать представление приборной панели и отображать зарегистрированные данные пользователями на интерфейсе.
def dashboard(request): if "user" in request.session: user=request.session["user"]["username"] context={"user":user} return render(request,"dashboard.html",context) else: return HttpResponseNotFound("Page not found")
При успешном входе в систему вы должны быть перенаправлены на страницу приборной панели, как видно на изображении ниже.
Создать функциональность викторины
Нам нужно позволить пользователям создавать новые викторины для участия. Чтобы сделать это обновление вашего Просмотр .py
Файл со следующим кодом:
def create_quiz(request): if request.method=="POST": name=request.POST.get("quiz_name") description=request.POST.get("quiz_description") total_questions=request.POST.get("total_questions") try: quiz = client.query(q.get(q.match(q.index("quiz_index"), name))) messages.add_message(request, messages.INFO, 'A Quiz with that name already exists.') return redirect("App:create-quiz") except: quiz = client.query(q.create(q.collection("Quiz"), { "data": { "status":"active", "name": name, "description": description, "total_questions": total_questions, } })) messages.add_message(request, messages.INFO, 'Quiz Created Successfully.') return redirect("App:create-quiz") return render(request,"create_quiz.html")
В указанном выше коде мы проверили, был ли был получен запрос на пост. Если это было, мы собрали «имя», «Описание» и «TOLLE_QUESTIONS», которые являются полями, необходимыми для создания викторины. Затем мы использовали «попробовать», чтобы кэшировать запрос нашего Викторина
Коллекция с нашими Quiz_index
Индекс, который проверяет, соответствует ли какая-либо другая викторина в базе данных, имена, указанное для создаваемого викторина. Если запрос не дает результатов, мы тогда позволяем создавать викторину.
Функциональность страницы викторины
Страница теста несет все созданные викторины и позволяет пользователям прокручивать их и выбрать кого-либо для участия. Обновите свой Просмотр .py
Файл со следующим кодом:
def quiz(request): try: all_quiz=client.query(q.paginate(q.match(q.index("quiz_get_index"), "active")))["data"] quiz_count=len(all_quiz) page_number = int(request.GET.get('page', 1)) quiz = client.query(q.get(q.ref(q.collection("Quiz"), all_quiz[page_number-1].id())))["data"] context={"count":quiz_count,"quiz":quiz, "next_page": min(quiz_count, page_number + 1), "prev_page": max(1, page_number - 1)} return render(request,"quiz.html",context) except: return render(request,"quiz.html")
В вышеперечисленном коде мы сделали запрос к клиенту FQL и создали запрос all_quiz.
используя Quiz_get_index
Индекс, чтобы проверить наличие викторин, которые активны. Затем мы создали пегирование Викторина
Чтобы запросить все данные в All_Quiz
Запрос, который мы создали ранее, используя номер страницы, запрашиваемого пользователем, и выполнил всю страницу и другие необходимые данные, используя контекст.
Как видно на изображении выше, пользователь может просматривать все викторины на каждой странице и нажмите на Начать тест
ответить на викторину его/ее выбора.
Создать вопросы функции
Эта функциональность позволяет пользователям создавать вопросы, которые будут отображаться в разных созданных викторинах. Обновите свой Просмотр .py
с кодом ниже.
def create_question(request): quiz_all=client.query(q.paginate(q.match(q.index("quiz_get_index"), "active"))) all_quiz=[] for i in quiz_all["data"]: all_quiz.append(q.get(q.ref(q.collection("Quiz"),i.id()))) context = {"quiz_all":client.query(all_quiz)} if request.method=="POST": quiz_name=request.POST.get("quiz_name") question_asked=request.POST.get("question") answer_1=request.POST.get("answer_1") answer_2=request.POST.get("answer_2") answer_3=request.POST.get("answer_3") answer_4=request.POST.get("answer_4") correct_answer=request.POST.get("correct_answer") try: question_create = client.query(q.get(q.match(q.index("question_index"), question_asked))) messages.add_message(request, messages.INFO, 'This question already exists') return redirect("App:create-question") except: question_create = client.query(q.create(q.collection("Question"), { "data": { "quiz_name": quiz_name, "question_asked": question_asked, "answer_1": answer_1, "answer_2": answer_2, "answer_3": answer_3, "answer_4": answer_4, "correct_answer": correct_answer, } })) messages.add_message(request, messages.INFO, 'Question Created Successfully.') return redirect("App:create-question") return render(request,"create-questions.html",context)
В вышеупомянутый код мы сделали запрос к клиенту FQL, используя Quiz_get_index
Чтобы проверить запрос всех данных в Викторина
Коллекция должна быть оказана на Создание вопросов.html
страница. Затем мы добавили все данные в запросе выше в All_Quiz
список. На данный момент мы проверили, был ли получен запрос на пост. Если это было, мы собрали все данные, предоставленные в почтовом запросе, необходимом для создания вопроса и сделали запрос, используя Вопрос_index
Индекс, чтобы проверить, есть ли какие-либо документы в нашем Вопрос:| Сборник с теми же данными, предоставленными для создания вопроса. Если бы не было никакого совпадения, мы приступили к созданию вопроса и оказали «успешно созданный вопрос» для перенаправления во время перенаправления обратно в
Создание вопросов.html Страница, чтобы избежать дубликатов данных на перезагрузке страницы.
Функциональность викторины ответа
Чтобы позволить пользователям отвечать на вопросы и забиться на викторине, обновите свой Просмотр .py
со следующим кодом:
def answer_quiz(request,slug): question_all=client.query(q.paginate(q.match(q.index("question_get_index"), slug)))["data"] question_count=len(question_all) page_number = int(request.GET.get('page', 1)) question = client.query(q.get(q.ref(q.collection("Question"), question_all[page_number-1].id())))["data"] if page_number==question_count: context={"question":question,"next_page": min(question_count, page_number + 1), "prev_page": max(1, page_number - 1),"finish":"true"} else: context={"question":question,"next_page": min(question_count, page_number + 1), "prev_page": max(1, page_number - 1)} if request.method=="POST": answer=request.POST.get("answer") question=request.POST.get("question") try: check_answer=client.query(q.get(q.match(q.index("answer_get_index"), request.session["user"]["username"],question)))["data"] messages.add_message(request, messages.INFO, 'You already answered this question') except Exception: answer_create = client.query(q.create(q.collection("Answers"), { "data": { "user": request.session["user"]["username"], "quiz": slug, "question": question, "answer": answer, } })) messages.add_message(request, messages.INFO, 'Answer Saved') if request.GET.get("finish")=="true": score=0 check_answer=client.query(q.paginate(q.match(q.index("answer_score_index"), request.session["user"]["username"],slug))) all_answer=[] for i in check_answer["data"]: all_answer.append(q.get(q.ref(q.collection("Answers"),i.id()))) answers=client.query(all_answer) for i in answers: try: mark_answer=client.query(q.get(q.match(q.index("question_answer"),i["data"]["answer"]))) score=score+1 except: score=score context={"score":score,"question_count":question_count} return render(request,"answer_quiz.html",context)
В указанном выше коде мы сделали запрос Вопрос_all
Чтобы получить тест, сопоставив удар, прошедший для конкретной страницы. Затем мы подсчитали количество вопросов в запросе Вопрос_count
и создал пагинацию Вопрос:| Сбор, соответствующий идентификатору страницы
Вопрос_all Запрос запрошен пользователем. Затем мы проверили, если текущий номер страницы равен последней странице в нашем запросе. Если это так, мы визуализируем «закончить» к контексту, который позволит пользователю нажать на кнопку «Готово» и завершить викторину. Мы также проверили, был ли получен запрос на почту, чтобы сделать представление ответа. Если бы был получен сообщение, мы проверяем, уже ответил ли пользователь, что конкретный вопрос, сделав запрос к клиенту FQL, используя
answer_get_index Индекс, чтобы соответствовать имени пользователя текущего пользователя и ответа на вопрос
Ответы . Если пользователь не ответил на этот вопрос, мы создаем запрос для создания этого ответа в
Ответы коллекция. Пользователь выбирает ответ на текущий вопрос и нажимает на
Сохранить кнопку ответа прежде чем приступить к следующему вопросу. Наконец, мы проверили, нажал ли пользователь на
Готово Кнопка, проверяя, если ". Мы устанавливаем оригинальный балл в тесте и создал запрос
check_answer Клиенту FQL, чтобы получить ответы, соответствующие конкретному викторину, ответили с помощью
answer_score_index Индекс создан ранее. Затем мы провели для цикла, чтобы добавить все данные в
check_answer в
all_answer список. На данный момент мы создали запрос, используя
all_answer Отказ Затем мы зацикливаемся через
all_answer Чтобы проверить, сохранены ли ответы, сохраненные пользователями
revent_answer поле для каждой данные в
Вопрос:| Коллекция с использованием Вопрос_answer
показатель. Мы кэшировали этот запрос запроса с помощью «TRY, кроме», так что за каждый раз оба ответы совпадают без ошибок, увеличившись на один (1). В противном случае счет остается прежним. Этот цикл работает совпадает со всеми ответами, предоставленными пользователем до получения окончательного балла. Затем мы оказываем этот счет к интерфейсу, используя контекст для пользователей, чтобы увидеть.
После выбора варианта для каждого вопроса пользователь должен нажать на Сохранить ответ
Кнопка, чтобы сохранить ответ на базу данных и нажмите на Следующий
перейти к следующему вопросу.
Как видно на изображении выше, после ответа на последний вопрос, пользователь может сохранить свой ответ и нажать на Готово
Кнопка, чтобы завершить викторину и увидеть его общий балл для этого викторина.
Оценка будет отображаться похожим на один на изображении ниже.
В этой статье мы построили приложение викторины с База данных Fauna Sersuless и джанго. Мы видели, насколько легко интегрировать фауну в приложение Python и получила возможность исследовать некоторые из своих основных функций и функциональных возможностей.
Исходный код нашего приложения для викторины доступен на Гадость . Если у вас есть какие-либо вопросы, не стесняйтесь обращаться ко мне в Twitter: @ Лорчукс3 Отказ
Оригинал: “https://dev.to/chukslord1/building-a-quiz-app-with-django-and-fauna-2ojo”