Django-DRF+Vue_note01

目录

后端:

前端:


后端:

# 数据库创建:

create database 数据库名字 DEFAULT CHARSET utf8 COLLATE utf8_general_ci;

# settings 更改

DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.mysql',
    'NAME':' ',   # 数据库名字
    'USER': ' ',
    'PASSWORD': ' ',
    'HOST': '127.0.0.1',
    'PORT': 3306,
    }
}

# 数据迁移

python manage.py makemigrations

python manage.py migrate

# 新建app (写入settings中)

python manage.py startapp app01

# 启动

python manage.py runserver

模板:

数据库设计models

class Author(models.Model):
    name = models.CharField(max_length=32, verbose_name="用户")
    age = models.IntegerField(verbose_name="年龄")

    def __str__(self):
        return self.name

app01用户接口

path('zz/', views.Zzview.as_view()),
re_path('zz/(?P<pk>\d+)/', views.Zzdetailview.as_view()),

views功能函数和增删改查

class Zzview(APIView):
    # 单个禁用 token 验证
    authentication_classes = [TokenAuthtication]

    def get(self, request):
        # 获取数据集(模型对象)
        students_data = Author.objects.all()
        pageNum = request.GET.get('pageNum', '')
        pageSize = request.GET.get('pageSize', '')
        # 过滤
        search_nick_term = request.GET.get('name', '')
        if search_nick_term:
            search_nick_term = search_nick_term.strip()
            students_data = students_data.filter(name__icontains=search_nick_term)
        # 自定义分页 过滤后再次分页
        paginator = Paginator(students_data, pageSize)
        page_obj = paginator.get_page(pageNum)
        # 拿到分页对象
        page_obj_dq = page_obj.object_list
        # 拿到总数
        page_obj_zs = paginator.count
        # 实例化序列化器,得到序列化器对象
        # 分页对象进行序列化
        ser = AuthorSerializer(instance=page_obj_dq, many=True)
        # 调用序列化器对象的data属性方法获取转换后的数据
        data = ser.data

        # 响应数据
        return Response(data={'code': 200, 'zs': page_obj_zs, 'data': data})

    def post(self, request):
        print(request.data)
        # 反序列化数据
        student = AuthorSerializer(data=request.data)
        # 校验不通过
        if not student.is_valid():
            # 返回错误信息
            return Response(data={'code': 500, 'data': student.errors})
        # 校验通过,保存数据
        student.save()
        # 响应数据
        return Response(data={'code': 200, 'message': '增加成功', 'data': student.data})
class Zzdetailview(APIView):
    authentication_classes = [TokenAuthtication]

    def get(self, request, pk):
        student = Author.objects.get(pk=pk)
        ser = AuthorSerializer(instance=student)
        return Response(ser.data)

    # 修改一个信息
    def put(self, request, pk):
        print(request.data)
        instance = Author.objects.get(pk=pk)
        ser = AuthorSerializer(instance=instance, data=request.data)
        if not ser.is_valid():
            return Response(data={'code': 500, 'message': ser.errors})
        ser.save()
        return Response(data={'code': 200, 'message': '修改成功', 'data': ser.data})

    # 删除一个信息
    def delete(self, request, pk):
        Author.objects.get(pk=pk).delete()
        return Response(data={'code': 200, 'message': '删除成功'})

序列化器serializer

from rest_framework import serializers
from rest_framework.serializers import ModelSerializer
from . import models

class GuanliModelSerializers(ModelSerializer):
    """管理员信息模型序列化器"""
    username = serializers.CharField(read_only=True)

    class Meta:
        model = models.Guanli
        fields = '__all__'

class PublishSerializer(serializers.ModelSerializer):
    class Meta:
        model=models.Publish
        fields = "__all__"

class AuthorSerializer(serializers.ModelSerializer):
    class Meta:
        model=models.Author
        fields = "__all__"

class BookInfoModelSerializermodel(serializers.ModelSerializer):
    # 使用PublishSerializer作为publish字段的嵌套序列化器
    publish = PublishSerializer(read_only=True)
    # 使用主键字段类型 并且将publish_id设置为"只写",也就是读取的时候不会返回!
    publish_id = serializers.PrimaryKeyRelatedField(queryset=models.Publish.objects.all(), source='publish',
                                                    write_only=True)

    # 使用AuthorSerializer作为author字段的嵌套序列化器
    authors = AuthorSerializer(read_only=True, many=True)
    # 使用主键字段类型 并且将author_id设置为"只写",也就是读取的时候不会返回!
    authors_id = serializers.PrimaryKeyRelatedField(queryset=models.Author.objects.all(), source='authors',
                                                    write_only=True, many=True)

    class Meta:
        model = models.Book
    
        fields = "__all__"

前端:

接口:

完整代码: 

<template>

  <el-button type="primary" @click="visible = true">添加作者</el-button>

  <el-card shadow="never" style="margin-top: 10px;">

    <!-- 查询区域 -->

    <el-card shadow="never" style="margin: 10px 0;">

      <el-form :model="search">

        <el-row :gutter="30">

          <el-col :xs="24" :sm="12" :md="8" :lg="6">

            <el-form-item label="作者名:">

              <el-input v-model="search.name" placeholder="请输入作者名:" />

            </el-form-item>

          </el-col>

        </el-row>

      </el-form>

      <div style="text-align: right;">

        <el-button type="primary" @click="getList()">查询</el-button>

        <el-button @click="resetSearch()">重置</el-button>

      </div>

    </el-card>

    <!-- 表格区域 -->

    <el-table :data="tableData" stripe>

      <el-table-column prop="id" label="ID" width="70" />

      <el-table-column prop="name" label="姓名" />

      <el-table-column prop="age" label="年纪" />

      <!-- <el-table-column prop="createdAt" label="创建时间" width="180" />

      <el-table-column prop="updatedAt" label="更新时间" width="180" /> -->

      <el-table-column label="操作" width="120" fixed="right">

        <template #default="scope">

          <el-button link type="primary" size="small" @click="editItem(scope.row)">编辑</el-button>

          <el-popconfirm title="确定要删除吗?" @confirm="deleteItem(scope.row.id)">

            <template #reference>

              <el-button link type="primary" size="small">删除</el-button>

            </template>

          </el-popconfirm>

        </template>

      </el-table-column>

    </el-table>

    <!-- 分页 -->

    <el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange"

      layout="sizes, total, prev, pager, next" :total="totalNum" :currentPage="search.pageNum"

      :pageSize="search.pageSize">

    </el-pagination>

  </el-card>

  <!-- 新增或编辑的抽屉 -->

  <sDrawer v-model="visible" :title="form.id ? '编辑作者' : '添加作者'" size="35%" :close-on-click-modal="false">

    <el-form :model="form" label-width="100px" ref="ruleFormRef">

      <el-form-item label="作者名称:">

        <el-input v-model="form.name" />

      </el-form-item>

    </el-form>

    <el-form :model="form" label-width="100px" ref="ruleFormRef">

      <el-form-item label="作者年纪:">

        <el-input v-model="form.age" />

      </el-form-item>

    </el-form>

    <template #footer>

      <el-button @click="visible = false">取消</el-button>

      <el-button type="primary" @click="saveData()">确定</el-button>

    </template>

  </sDrawer>

</template>

<script>

import sDrawer from "@/components/s-drawer/s-drawer.vue"

export default {

  components: {

    sDrawer,

  },

  watch: {

    visible(value) {

      if (!value) {

        this.form = {}

      }

    }

  },

  data() {

    return {

      form: {

      },

      visible: false,

      tableData: [],

      totalNum: 100,

      search: {

        pageNum: 1,

        pageSize: 10,

        // token: "",

      },

    };

  },

  created() {

    // this.search.token = localStorage.getItem("token");

    this.getList();

  },

  methods: {

    async getList() {

      const res = await this.$request.get(

        "/tushu/zz/",

        { params: this.search }

      );

     

      if (res.data.code === 200) {

        // this.tableData = res.data.data.sort((a, b)      

        console.log(res.data)

        this.tableData = res.data.data;

        this.totalNum = res.data.zs

      }

    },

    // 每页条数改变时触发 选择一页显示多少行

    handleSizeChange(val) {

      console.log(`每页 ${val} 条`);

      this.search.pageSize = val;

      this.getList();

    },

    // 当前页改变时触发 跳转其他页

    handleCurrentChange(val) {

      console.log(`当前页: ${val}`);

      this.search.pageNum = val;

      this.getList();

    },

    resetSearch() {

      let search = {

        pageNum: this.search.pageNum,

        pageSize: this.search.pageSize,

      };

      this.search = search;

      this.getList();

    },

    editItem(row) {

      this.form = this.$deepClone(row)

      this.visible = true

    },

    async saveData() {

      if (this.form.id) {

        const res = await this.$request.put('/tushu/zz/' + this.form.id + '/', this.form)

        if (res.data.code === 200) {

        this.$message.success(res.data.message)

        this.getList()

        this.visible = false

      }

      } else {

        const res = await this.$request.post('/tushu/zz/', this.form)

        if (res.data.code === 200) {

        this.$message.success(res.data.message)

        this.getList()

        this.visible = false

      }

      }

      // const res = await this.$request.post(this.form.id ? '/tushu/guanli/' : '/tushu/guanli/', this.form)

      // if (res.data.code === 200) {

      //   this.$message.success(res.data.message)

      //   this.getList()

      //   this.visible = false

      // }

    },

    async deleteItem(id) {

      const res = await this.$request.delete("/tushu/zz/" + id + '/')

      if (res.data.code === 200) {

        this.$message.success(res.data.message)

        this.getList()

      }

    },



 

    // 照片文件超出个数限制时的钩子

    handleExceed(files, fileList) {

      this.$notify.warning({

      title: '警告',

      message: `只能选择 ${this.limitNum} 个文件,当前共选择了 ${files.length + fileList.length} 个`

      })

    },

    // 上传照片文件之前的钩子

    handleBeforeUpload(file) {

      const size = file.size / 1024 / 1024

          if (size > 1) {

            this.$notify.warning({

            title: '警告',

            message: '图片大小必须小于1M'

          })

      }

    },

    handleSuccess1(res) {

        console.log(res.data,'777777777777777777777777777777777777777')

        this.form.img_url = res.data.file

        this.dialogImageUrl = ''

        this.$notify({

            title: '通知',

            message: '上传照片成功~',

            type: 'success',

            duration: 5000

      })

    },



 

  },

};

</script>

<style scoped>

.el-pagination {

  margin-top: 10px;

}

.el-row {

  margin-bottom: 20px;

}

.el-row:last-child {

  margin-bottom: 0px;

}

</style>

(如果前端使用的是html的话要添加)

在form表单添加框选的内容(如果是POST请求)加上{% csrf_token %}

因为创建的是静态static文件,所以要在.html第一行加上{% load static % }

23.9-- 

  • 11
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值