django+vue+mysql建一个答题库
用 Vue 和 Django 构建在线答题网页涉及前端、后端和数据库部分。下面是一个基本步骤指南,涵盖前端、后端、以及数据库配置等内容。
技术栈
- 前端: Vue.js
- 后端: Django
- 数据库: MySQL
- 身份验证: Django 自带身份验证系统或 Django REST Framework 的身份验证
项目步骤
1. 搭建 Django 后端
1.1. 创建 Django 项目
django-admin startproject quiz_project
cd quiz_project
1.2. 创建 Django 应用
python manage.py startapp quiz
1.3. 配置 Django 项目
在 quiz_project/settings.py
中,添加 quiz
应用到 INSTALLED_APPS
中,并配置数据库连接。
# INSTALLED_APPS
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'quiz', # Our custom quiz app
]
# DATABASES
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'quiz_db', # Your MySQL database name
'USER': 'root', # Your MySQL username
'PASSWORD': 'yourpassword', # Your MySQL password
'HOST': 'localhost', # MySQL server address
'PORT': '3306', # MySQL port
}
}
1.4. 数据库迁移
python manage.py makemigrations
python manage.py migrate
1.5. 创建 Django 模型
在 quiz/models.py
中创建模型以存储题目和答案。
from django.db import models
from django.contrib.auth.models import User
class Question(models.Model):
question_text = models.CharField(max_length=200)
correct_answer = models.CharField(max_length=100)
created_at = models.DateTimeField(auto_now_add=True)
class Answer(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
question = models.ForeignKey(Question, on_delete=models.CASCADE)
user_answer = models.CharField(max_length=100)
is_correct = models.BooleanField(default=False)
answered_at = models.DateTimeField(auto_now_add=True)
1.6. 注册模型到 Django 管理界面
在 quiz/admin.py
中注册 Question
和 Answer
模型。
from django.contrib import admin
from .models import Question, Answer
admin.site.register(Question)
admin.site.register(Answer)
2. 设置 Vue 前端
2.1. 创建 Vue 项目
vue create quiz-app
cd quiz-app
选择默认配置或根据需要自定义配置。
2.2. 安装 Axios
Axios 用于从前端与后端通信。
npm install axios
2.3. 创建组件
在 src/components
下创建注册、登录、答题组件。
2.3.1. 注册组件
<template>
<div>
<h2>Register</h2>
<form @submit.prevent="register">
<div>
<label for="username">Username</label>
<input type="text" v-model="username" required />
</div>
<div>
<label for="password">Password</label>
<input type="password" v-model="password" required />
</div>
<button type="submit">Register</button>
</form>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
username: '',
password: '',
};
},
methods: {
register() {
axios
.post('/api/register/', {
username: this.username,
password: this.password,
})
.then((response) => {
console.log('Registration successful:', response.data);
})
.catch((error) => {
console.error('Error registering:', error.response.data);
});
},
},
};
</script>
2.3.2. 登录组件
<template>
<div>
<h2>Login</h2>
<form @submit.prevent="login">
<div>
<label for="username">Username</label>
<input type="text" v-model="username" required />
</div>
<div>
<label for="password">Password</label>
<input type="password" v-model="password" required />
</div>
<button type="submit">Login</button>
</form>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
username: '',
password: '',
};
},
methods: {
login() {
axios
.post('/api/login/', {
username: this.username,
password: this.password,
})
.then((response) => {
console.log('Login successful:', response.data);
})
.catch((error) => {
console.error('Error logging in:', error.response.data);
});
},
},
};
</script>
2.3.3. 答题组件
<template>
<div>
<h2>Quiz</h2>
<div v-if="question">
<p>{{ question.question_text }}</p>
<form @submit.prevent="submitAnswer">
<input type="text" v-model="userAnswer" required />
<button type="submit">Submit Answer</button>
</form>
</div>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
question: null,
userAnswer: '',
};
},
mounted() {
this.fetchQuestion();
},
methods: {
fetchQuestion() {
axios
.get('/api/question/')
.then((response) => {
this.question = response.data;
})
.catch((error) => {
console.error('Error fetching question:', error.response.data);
});
},
submitAnswer() {
axios
.post('/api/answer/', {
question_id: this.question.id,
user_answer: this.userAnswer,
})
.then((response) => {
console.log('Answer submitted:', response.data);
this.fetchQuestion(); // Get next question
})
.catch((error) => {
console.error('Error submitting answer:', error.response.data);
});
},
},
};
</script>
3. 配置 Django REST API
在 Django 中创建 API 以处理注册、登录、提问和提交答案。
3.1. 安装 Django REST Framework
pip install djangorestframework
3.2. 添加 Django REST Framework 配置
在 quiz_project/settings.py
中添加 Django REST Framework 到 INSTALLED_APPS
并配置 REST_FRAMEWORK。
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework', # Django REST Framework
'quiz', # Quiz app
]
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication',
),
}
3.3. 创建 Django REST API 视图
在 quiz/views.py
中,创建 API 视图以处理注册、登录、提问和答案提交。
from rest_framework import serializers, views, response, permissions
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login
from .models import Question, Answer
# User Serializer for registration and login
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['id', 'username']
# Question Serializer
class QuestionSerializer(serializers.ModelSerializer):
class Meta:
model = Question
fields = ['id', 'question_text']
# Answer Serializer
class AnswerSerializer(serializers.ModelSerializer):
class Meta:
model = Answer
fields = ['id', 'user', 'question', 'user_answer', 'is_correct']
# API for registration
class RegisterAPI(views.APIView):
permission_classes = [permissions.AllowAny]
def post(self, request):
username = request.data.get('username')
password = request.data.get('password')
user = User.objects.create_user(username, password)
return response.Response({
'user': UserSerializer(user).data
})
# API for login
class LoginAPI(views.APIView):
permission_classes = [permissions.AllowAny]
def post(self, request):
username = request.data.get('username')
password = request.data.get('password')
user = authenticate(request, username=username, password=password)
if user:
login(request, user)
return response.Response({
'user': UserSerializer(user).data
})
return response.Response({
'message': 'Invalid credentials'
}, status=401)
# API to fetch a question
class QuestionAPI(views.APIView):
permission_classes = [permissions.IsAuthenticated]
def get(self, request):
question = Question.objects.order_by('?').first() # Random question
if question:
return response.Response({
'question': QuestionSerializer(question).data
})
return response.Response({
'message': 'No questions available'
}, status=404)
# API to submit an answer
class AnswerAPI(views.APIView):
permission_classes = [permissions.IsAuthenticated]
def post(self, request):
question_id = request.data.get('question_id')
user_answer = request.data.get('user_answer')
question = Question.objects.get(pk=question_id)
is_correct = user_answer.lower() == question.correct_answer.lower()
answer = Answer.objects.create(
user=request.user,
question=question,
user_answer=user_answer,
is_correct=is_correct,
)
return response.Response({
'answer': AnswerSerializer(answer).data,
'correct': is_correct,
})
3.4. 配置 Django 路由
在 quiz/urls.py
中配置 API 路由。
from django.urls import path
from . import views
urlpatterns = [
path('register/', views.RegisterAPI.as_view(), name='register'),
path('login/', views.LoginAPI.as_view(), name='login'),
path('question/', views.QuestionAPI.as_view(), name='question'),
path('answer/', views.AnswerAPI.as_view(), name='answer'),
]
然后在 quiz_project/urls.py
中包括 quiz/urls.py
。
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('quiz.urls')), # Include quiz API routes
]
4. 整合 Django 和 Vue
为了让 Vue 和 Django 一起工作,可以使用 Django 的静态文件和模板系统,或使用 Django REST Framework 完全分离前后端。
4.1. 处理 Django 和 Vue 的跨域问题
可以使用 Django-CORS-Headers 来允许 Vue 前端与 Django 后端通信。
pip install django-cors-headers
然后在 quiz_project/settings.py
中配置 CORS。
INSTALLED_APPS += ['corsheaders']
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
# other middlewares...
]
CORS_ORIGIN_ALLOW_ALL = True # 在开发过程中允许所有来源
5. 运行项目
确保 Django 和 MySQL 正常工作,并且前后端都已配置好。
5.1. 运行 Django 后端
python manage.py runserver
5.2. 运行 Vue 前端
npm run serve
访问 Vue 应用并测试注册、登录、答题等功能。确认后端 API 和前端组件的正确交互。
6. 完成
现在你应该拥有一个基于 Vue 和 Django 的在线答题网页,具备注册、登录、答题等基本功能。根据需要扩展更多功能,如题库管理、成绩统计等。