准备工作
1. 创建django项目和应用
创建项目:django-admin startproject 项目名
创建子应用: python manage.py startapp 子应用名
2.项目配置
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',# drf框架
'corsheaders', # 跨域
'student',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'corsheaders.middleware.CorsMiddleware', # 跨域中间件
]
# 允许所有元访问
CORS_ORIGIN_ALLOW_ALL = True
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'HOST':'localhost',
'POST':3306,
'USER':'root',
'PASSWORD':'123123',
'NAME':'project9',
}
}
LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'Asia/Shanghai'
3.安装数据库
在子应用同名的文件夹中的 init 文件
import pymysql
pymysql.install_as_MySQLdb()
后端
1.编写模型类
from django.db import models
# Create your models here.
# 老师模型
class Teacher(models.Model):
tea_name = models.CharField(max_length=20,verbose_name='老师名称')
class Meta:
db_table='teacher'
verbose_name = '老师表'
verbose_name_plural=verbose_name
def __str__(self):
return self.tea_name
class Student(models.Model):
stu_name = models.CharField(max_length=20,verbose_name='学生姓名')
score = models.IntegerField(verbose_name='成绩')
sex = models.CharField(max_length=5,verbose_name='性别')
teacher = models.ForeignKey(to=Teacher,on_delete=models.CASCADE,verbose_name='老师')
class Meta:
db_table='student'
verbose_name = '学生表'
verbose_name_plural=verbose_name
def __str__(self):
return self.stu_name
2.注册表
在admin文件
from django.contrib import admin
from student.models import Teacher,Student
# Register your models here.
admin.site.register(Teacher)
admin.site.register(Student)
3.迁移、执行迁移
生成迁移:python manage.py makemigrations
执行迁移: python manage.py migrate
4.生成超级用户,添加数据
创建超级用户: python manage.py createsuperuser
5.路由分发
在子应用下创建urls.py文件
# 子路由
from django.urls import path
urlpatterns = [
]
与项目名同名文件的urls.py
# 主路由
from django.contrib import admin
from django.urls import path, include
from student import urls
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(urls)),
]
6.序列化器
在子应用下新建文件serializers.py 文件
from rest_framework import serializers
from student.models import Teacher,Student
class TeacherSerializer(serializers.ModelSerializer):
class Meta:
model = Teacher
fields = '__all__'
class StudentSerializer(serializers.ModelSerializer):
class Meta:
model = Student
fields = '__all__'
7.外键序列化器
有5种,第一种可以反序列,其他只能进行序列化
- 默认外键序列化器,使用外键的主键字段
- StringRelated外键序列化,使用外键表的str方式进行序列化
- SlugRelated外键序列化,指定字段进行序列化。
- PrimaryKeyRelatedField外键序列化,使用外键表的主键进行序列化。
- 外键自定义序列化方式,使用自定义方法进行序列化。
# 只能进行序列化,不能进行反序列化
class StudentSerializer2(serializers.ModelSerializer):
# 1.使用外键表str方法进行序列化
# teacher = serializers.StringRelatedField()
# 2.指定字段进行序列化
# teacher = serializers.SlugRelatedField(read_only=True,slug_field='tea_name')
# 3.使用外键表的主键进行序列化
# teacher = serializers.PrimaryKeyRelatedField(read_only=True)
# 4.使用自定义方法进行序列化,字段自定义(名字自己取)
tea_name = serializers.SerializerMethodField(read_only=True)
# obj是模型类对象
def get_tea_name(self,obj):
return obj.teacher.tea_name
class Meta:
model = Student
fields = '__all__'
8. 视图
老师、学生视图,增删改查操作
学生视图有两个,分为有参数和无参数
前端调用时要注意
studentview3 这个视图是为了前端根据老师姓名,来查询对应的学生信息创建
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from student.models import Teacher,Student
from student.serializer import TeacherSerializer,StudentSerializer,StudentSerializer2
# Create your views here.
# 老师视图
class TeacherView(APIView):
def get(self,request):
teachers = Teacher.objects.all()
ser = TeacherSerializer(instance=teachers,many=True)
return Response(ser.data,status=200)
class StudentView(APIView):
# 查询所有学生信息
def get(self,request):
stu_data = Student.objects.all()
# 序列化
ser = StudentSerializer(instance=stu_data,many=True)
# 返回数据.data
return Response(ser.data,status=200)
# 添加学生信息
def post(self,request):
ser = StudentSerializer(data=request.data)
# 判断反序列化是否成功
if ser.is_valid(raise_exception=True):
ser.save()
return Response({'msg':'success'},status=201)
return Response({'msg':'error'})
class StudentView2(APIView):
def put(self,request,id):
try:
stu_data = Student.objects.get(id=id)
except Exception as e:
print(e)
return Response({'msg': 'error'},status=404)
ser = StudentSerializer(instance=stu_data,data=request.data)
if ser.is_valid(raise_exception=True):
ser.save()
return Response({'msg':'success'},status=201)
return Response({'msg':'error'})
def delete(self,request,id):
try:
Student.objects.filter(id=id).delete()
except Exception as e:
print(e)
return Response({'msg': 'error'},status=404)
return Response({'msg': 'success'}, status=204)
class StudentView3(APIView):
# 根据老师id查询对应学生信息
def get(self,request,id):
stu_data = Student.objects.filter(teacher_id=id)
ser = StudentSerializer2(instance=stu_data,many=True)
return Response(ser.data,status=200)
9.路由配置
from django.urls import path
from student import views
urlpatterns = [
path('student/',views.StudentView.as_view()), # 学生路由
path('teacher/',views.TeacherView.as_view()), # 老师路由
path('student/<int:id>/',views.StudentView2.as_view()),
path('stu/<int:id>/',views.StudentView3.as_view()), # 根据老师id获取学生信息
]
前端
实现功能:
1.在主页面展示所有老师信息。
2.点击老师姓名可以转跳到子页面展示对应的学生信息。
3.学生信息的删除。
4.学生信息的添加。
5.学生信息的修改。
1)创建vue项目,进行配置
创建项目 :vue create 项目名
2) 安装axios
一定要进入到项目文件的路径
npm install axios --save
3)配置跨域
在根目录下创建vue.config.js文件
module.exports ={
devServer:{
proxy:'http://127.0.0.1:8000/'
}
}
4) 封装请求
在str文件夹下-创建utils文件夹-创建request.js文件
import Axios from 'axios'
export function get(url,params){
return Axios.get(url,params)
}
export function post(url,params){
return Axios.post(url,params)
}
export function put(url,params){
return Axios.put(url,params)
}
export function del(url,params){
return Axios.delete(url,params)
}
5) 创建页面
在str文件下的views文件夹-创建stu文件-创建两个页面
6) 配置路由
在router文件下的index.js文件
import { createRouter, createWebHistory } from 'vue-router'
import TeaView from '../views/stu/TeaView.vue'
import StuView from '../views/stu/StuView.vue'
const routes = [
{
path: '/',
name: 'TeaView',
component: TeaView
},
{
path: '/stu',
name: 'StuView',
component: StuView
},
7) 配置链接
在APP.vue文件
<router-link to="/">Tea</router-link> |
<router-link to="/stu">Stu</router-link>
8) Tea页面
<template>
<div>
<h3>老师页面</h3>
<table width='500px' border="1px" align='center'>
<tr>
<th>编号</th>
<th>老师姓名</th>
</tr>
<tr v-for="(item,i) in tealist" :key="i">
<th>{{item.id}}</th>
<th>
<!-- v-bind 缩写 : 跳转页面名 携带参数-->
<router-link :to="{name:'StuView',params:{id:item.id}}">
{{item.tea_name}}
</router-link>
</th>
</tr>
</table>
</div>
</template>
<script>
import {get} from '../../utils/request.js'
export default {
name:'TeaView',
data(){
return{
tealist:[]
}
},
mounted(){
get('teacher/').then((resp)=>{
console.log(resp)
this.tealist = resp.data
}).catch((err)=>{
console.log(err)
})
}
}
</script>
<style>
</style>
9)Stu页面
注意:在写更新时一定注意字段名
<template>
<div>
<h3>学生页面</h3>
<table width='500px' border="1px" align='center'>
<tr>
<th>编号</th>
<th>学生姓名</th>
<th>成绩</th>
<th>性别</th>
<th>老师</th>
<th>操作</th>
</tr>
<tr v-for="(item,i) in stu_data" :key="i">
<th>{{item.id}}</th>
<th>{{item.stu_name}}</th>
<th>{{item.score}}</th>
<th>{{item.sex}}</th>
<th>{{item.tea_name}}</th>
<th>
<button @click="remove(item.id)">删除</button>
<!-- 根据学生id在表单展示学生信息 -->
<button @click="getData(i)">更新</button>
</th>
</tr>
</table>
<p>更新学生信息</p>
<p>姓名:<input type="text" v-model="name"></p>
<p>成绩:<input type="text" v-model="score"></p>
<p>性别:<input type="text" v-model="sex"></p>
<p>老师编号:<input type="text" v-model="tea"></p>
<p><button @click="update">更新</button></p>
</div>
</template>
<script>
import {get,del,put} from '../../utils/request.js'
export default {
name:'StuView',
data(){
return{
tea_id:this.$route.params.id,
stu_data:[],
name :"",
score:0,
sex:"",
tea:1,
id:0
}
},
mounted(){
this.getStudata();
},
methods:{
getData(i){
this.id = this.stu_data[i].id
this.name = this.stu_data[i].stu_name;
this.score = this.stu_data[i].score;
this.sex = this.stu_data[i].sex;
this.tea = this.stu_data[i].teacher;
},
update(){
let url = 'student/'+this.id+'/';
let obj = {stu_name:this.name,score:this.score,sex:this.sex,teacher:this.tea}
put(url,obj).then((resp)=>{
console.log(resp)
this.getStudata()
}).catch((err)=>{
console.log(err)
})
},
// 根据老师id获取信息
// 这个方法需要多次复用,所以封装成函数
getStudata(){
// 根据老师id查询动态信息
// url:'stu/'+'老师id' + '/'
let url = 'stu/' + this.tea_id + '/';
get(url).then((resp)=>{
console.log(resp)
this.stu_data = resp.data
}).catch((err)=>{
console.log(err)
})
},
remove(id){
// url = 'student/' + 'id' + '/'
let url = 'student/' + id + '/';
del(url).then((resp)=>{
console.log(resp)
this.getStudata()
}).catch((err)=>{
console.log(err)
})
}
}
}
</script>
<style>
</style>