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

基于Django API的NextJS项目:最优CRUD架构模式选型

解决方案:跳过Next.js API直接对接GeoDjango的CRUD架构设计

一、首选方案:构建独立的CRUD服务层

直接封装自定义服务层是最清晰的方案,它职责单一(专注于和GeoDjango的交互),避免页面中零散的fetch调用,还能统一处理JWT令牌和请求异常。

实现步骤:

  1. 在项目根目录创建services/api.js,封装基础请求逻辑和CRUD方法:
import { getSession } from 'next-auth/react';

// 基础请求封装:自动携带JWT、处理请求头和异常
const apiRequest = async (url, options = {}) => {
  const session = await getSession();
  const baseHeaders = {
    'Content-Type': 'application/json',
    ...(session?.user?.token && { Authorization: `Bearer ${session.user.token}` })
  };

  const response = await fetch(`https://你的GeoDjango域名${url}`, {
    ...options,
    headers: { ...baseHeaders, ...options.headers }
  });

  if (!response.ok) {
    throw new Error(`请求失败: ${response.status} ${response.statusText}`);
  }

  return response.json();
};

// 封装GeoDjango的CRUD接口
export const geoAPI = {
  // 读取类接口(整合你已完成的逻辑)
  getLocations: () => apiRequest('/api/locations/'),
  getLocationById: (id) => apiRequest(`/api/locations/${id}/`),
  
  // 写入类接口
  createLocation: (data) => apiRequest('/api/locations/', {
    method: 'POST',
    body: JSON.stringify(data)
  }),
  updateLocation: (id, data) => apiRequest(`/api/locations/${id}/`, {
    method: 'PUT',
    body: JSON.stringify(data)
  }),
  deleteLocation: (id) => apiRequest(`/api/locations/${id}/`, {
    method: 'DELETE'
  })
};
  1. 在页面/组件中直接调用服务层:
import { geoAPI } from '../services/api';

const CreateLocationPage = () => {
  const handleSubmit = async (formData) => {
    try {
      await geoAPI.createLocation(formData);
      // 处理成功逻辑:比如跳转列表页、提示用户
    } catch (err) {
      // 统一处理错误:比如弹窗提示、日志上报
      console.error('创建失败:', err);
    }
  };

  return (
    <form onSubmit={(e) => {
      e.preventDefault();
      handleSubmit(new FormData(e.target));
    }}>
      {/* 表单内容 */}
    </form>
  );
};

export default CreateLocationPage;

二、为什么不选Context或Middleware?

  • Context:它的核心作用是全局状态共享(比如用户信息、主题配置),如果用来封装CRUD会让Context职责过重,且每次调用都要通过useContext消费,不如直接导入服务层简洁。
  • Middleware:Next.js的Middleware是处理路由级拦截(比如权限校验、重定向)的工具,完全不适合用来封装数据操作逻辑,属于误用场景。

三、Next.js替代Vue Store的方案

如果需要全局状态管理(比如缓存请求结果、同步数据状态),推荐两种方案:

  1. TanStack Query(原React Query):专门针对服务器数据的状态管理,自带缓存、自动刷新、失效机制,完美替代Vue Store中数据获取和状态维护的逻辑。结合服务层使用示例:
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { geoAPI } from '../services/api';

const LocationsPage = () => {
  const queryClient = useQueryClient();
  
  // 查询列表,自动缓存
  const { data: locations } = useQuery({
    queryKey: ['locations'],
    queryFn: geoAPI.getLocations
  });

  // 创建数据的Mutation,成功后自动刷新列表缓存
  const createMutation = useMutation({
    mutationFn: geoAPI.createLocation,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['locations'] });
    }
  });

  return (
    <>
      <button 
        onClick={() => createMutation.mutate(你的表单数据)}
        disabled={createMutation.isLoading}
      >
        添加位置
      </button>
      {locations?.map(loc => (
        <div key={loc.id}>{loc.name}</div>
      ))}
    </>
  );
};
  1. Zustand:轻量级全局状态库,如果需要维护非服务器数据的全局状态(比如表单草稿、UI开关状态),比Redux简单太多,适合中小型项目。

四、NextAuth JWT的最佳实践

  • 客户端组件中用getSession()获取令牌,服务层已经自动处理请求头携带逻辑,无需手动拼接。
  • 服务器组件/getServerSideProps中用getServerSession()获取令牌:
import { getServerSession } from 'next-auth/next';
import { authOptions } from '../pages/api/auth/[...nextauth]';

export const getServerSideProps = async () => {
  const session = await getServerSession(authOptions);
  const response = await fetch(`https://你的GeoDjango域名/api/locations/`, {
    headers: {
      ...(session?.user?.token && { Authorization: `Bearer ${session.user.token}` })
    }
  });
  const locations = await response.json();

  return { props: { locations } };
};
  • 务必在GeoDjango中配置CORS,允许你的Vercel域名发起跨域请求,否则会出现跨域报错。

推荐项目结构

你的Next.js项目/
├── services/
│   └── api.js          # CRUD服务层
├── components/
│   └── LocationForm.js # 表单组件
├── pages/
│   ├── locations.js    # 列表页
│   └── create.js       # 创建页
└── utils/
    └── auth.js         # 可选:封装NextAuth工具方法

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 14:00:56