You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React-Django项目:传递Token并按用户地区过滤学校数据

解决方案:按Token中地区ID过滤学校列表

需求说明

当前项目中Schools.js会展示所有学校,需要调整为仅展示满足以下条件的学校:

  • dist_office_id 等于用户Token中的place_id字段值
  • school_name 不为空

同时需要将前端Token传递到后端,动态提取place_id,替换当前硬编码的place_id=3逻辑,适配不同地区办公人员的权限。


前端代码修改

1. 更新SchoolService.js,携带Token请求头

修改getSchools函数,添加Authorization请求头,把前端的JWT Token传给后端:

import axios from 'axios';

export function getSchools(token) {
    // 配置请求头,携带JWT Token
    const config = {
        headers: {
            'Authorization': `Bearer ${JSON.parse(token)}`
        }
    };
    return axios.get("http://127.0.0.1:8000/api/schools/", config)
    .then(response => response.data)
}

2. 更新Schools.js,传递Token并处理请求

修改useEffect中的调用逻辑,把本地存储的Token传给getSchools,同时优化Token判断逻辑:

import { useEffect, useState } from 'react';
import jwt_decode from "jwt-decode";
import {Table, Button, ButtonToolbar} from 'react-bootstrap';
import {FaEdit} from 'react-icons/fa';
import {RiDeleteBin5Line} from 'react-icons/ri';
import {getSchools, deleteSchool} from '../services/SchoolService';
import AddSchoolModal from '../components/modals/api_modals/AddSchoolModal';
import UpdateSchoolModal from '../components/modals/api_modals/UpdateSchoolModal';


const Schools = () => {
    const [schools, setSchools] = useState([]);
    const [addModalShow, setAddModalShow] = useState(false);
    const [editModalShow, setEditModalShow] = useState(false);
    const [editSchool, setEditSchool] = useState([]);
    const [isUpdated, setIsUpdated] = useState(false);

    // 获取本地存储的Token
    const token = localStorage.getItem("authTokens");

    useEffect(() => {
        let mounted = true;
        if(schools.length && !isUpdated) {
            return;
        }
        // 仅当存在Token时发起请求
        if(token) {
            getSchools(token)
                .then(data => {
                    if (mounted) {
                        setSchools(data);
                    }
                })
                .catch(err => {
                    console.error("获取学校列表失败:", err);
                })
        }
        return () => {
            mounted = false;
            setIsUpdated(false);
        }
    }, [isUpdated, schools, token]);

    // 以下原有逻辑保持不变
    const handleAdd = (e) => {
        e.preventDefault();
        setAddModalShow(true);
    };

    const handleUpdate = (e, school) => {
        e.preventDefault();
        setEditModalShow(true);
        setEditSchool(school);
    };

    const handleDelete = (e, id) => {
        if(window.confirm('Are you sure?')) {
            e.preventDefault();
            deleteSchool(id)
            .then((result) => {
                alert(result);
                setIsUpdated(true);
            },
            (error) => {
                alert("Failed to Delete!");
            })
        }

    };

    let AddModalClose = () => setAddModalShow(false);
    let EditModalClose = () => setEditModalShow(false);

     return (
        <div className="row side-row">
        <Table striped bordered hover size="sm">
          <thead>
            <tr>
              <th>S/N</th>
              <th>School</th>
              <th>Action</th>
            </tr>
          </thead>
          <tbody>
            {schools.map((school, index) =>
                <tr key={school.id}>
                  <td>{index + 1}</td>
                  <td>{school.school_name}</td>
                  <td>
                    <Button className='mr-2' variant="danger"  size="sm"
                        onClick={event => handleDelete(event,school.id)}>
                        <RiDeleteBin5Line />
                    </Button>
                    <span>&nbsp;&nbsp;</span>
                    <Button className='mr-2' variant="primary"  size="sm"
                        onClick={event => handleUpdate(event,school)}>
                        <FaEdit />
                    </Button>
                    <UpdateSchoolModal show={editModalShow} onHide={EditModalClose}
                    school={editSchool} setUpdated={setIsUpdated}>
                    </UpdateSchoolModal>
                  </td>
                </tr>)}
          </tbody>
        </Table>
        <ButtonToolbar>
            <Button variant="success" onClick={handleAdd}>Add School</Button>{' '}
            <AddSchoolModal show={addModalShow} onHide={AddModalClose} setUpdated={setIsUpdated}>
            </AddSchoolModal>
        </ButtonToolbar>
        </div>
      );
};

export default Schools;

后端代码修改(views.py)

修改SchoolView的get方法,从请求头的Token中解析出place_id,替换硬编码逻辑:

import jwt
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.exceptions import AuthenticationFailed, Http404
from .models import Place
from .serializers import PlaceSerializer

class SchoolView(APIView):
    def get_school(self, pk):
        try:
            school = Place.objects.get(id=pk)
            return school
        except Place.DoesNotExist:
            raise Http404

    def get(self, request, pk=None):
        if pk:
            data = self.get_school(pk)
            serializer = PlaceSerializer(data)
        else:
            # 从Authorization头中提取Token
            auth_header = request.headers.get('Authorization')
            if not auth_header or not auth_header.startswith('Bearer '):
                raise AuthenticationFailed('Invalid or missing token')
            
            token = auth_header.split(' ')[1]
            try:
                # 解析Token,替换为项目实际使用的JWT密钥
                decoded_token = jwt.decode(token, 'your_jwt_secret_key', algorithms=['HS256'])
                place_id = decoded_token.get('place_id')
            except jwt.ExpiredSignatureError:
                raise AuthenticationFailed('Token expired')
            except jwt.InvalidTokenError:
                raise AuthenticationFailed('Invalid token')

            # 按条件过滤学校:dist_office_id匹配且school_name不为空
            if place_id is not None:
                data = Place.objects.filter(dist_office_id=place_id, school_name__isnull=False)
                serializer = PlaceSerializer(data, many=True)
            else:
                # 无place_id时返回空列表
                data = Place.objects.none()
                serializer = PlaceSerializer(data, many=True)

        return Response(serializer.data)

注意事项

  • 替换代码中的your_jwt_secret_key为项目实际使用的JWT密钥
  • 确保Django项目已安装pyjwt库,可通过pip install pyjwt安装
  • 前端存储的authTokens是JSON字符串,请求时需用JSON.parse(token)解析为原始Token

内容的提问来源于stack exchange,提问作者Hamid Baisaana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 00:24:53