Angular 5前端向Django Rest Framework后端发送Post请求求助
看起来你已经在DRF端搭好了基础,能通过自带的API界面提交请求,那前端这边的问题大概率是跨域、请求格式或者CSRF的问题。我给你梳理一下完整的实现步骤,包括后端的必要配置和Angular 5的代码:
先补全后端的关键代码(假设你还没完善)
首先先把你的序列化器和视图补全,确保DRF接口是正常的:
models.py(你的现有代码)
class UserForm(models.Model): id_user_form = models.AutoField(primary_key=True) user = models.ForeignKey(User, on_delete=models.CASCADE, db_column='idUser', unique=False) name = models.CharField(max_length=50) type = models.CharField(max_length=25) location = models.CharField(max_length=200)
serializers.py
from rest_framework import serializers from .models import UserForm class UserFormSerializer(serializers.ModelSerializer): class Meta: model = UserForm fields = ['id_user_form', 'user', 'name', 'type', 'location']
views.py
from rest_framework import viewsets from .models import UserForm from .serializers import UserFormSerializer class UserFormViewSet(viewsets.ModelViewSet): queryset = UserForm.objects.all() serializer_class = UserFormSerializer
urls.py
from django.urls import path, include from rest_framework.routers import DefaultRouter from .views import UserFormViewSet router = DefaultRouter() router.register(r'user-forms', UserFormViewSet) urlpatterns = [ path('', include(router.urls)), ]
解决跨域问题(必做)
因为Angular和DRF通常跑在不同端口,必须处理跨域:
- 安装Django跨域插件:
pip install django-cors-headers
- 在
settings.py中配置:
INSTALLED_APPS = [ # ... 你的其他APP 'corsheaders', ] MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', # 要放在CommonMiddleware前面 'django.middleware.common.CommonMiddleware', # ... 其他中间件 ] # 开发环境可以允许所有域名,生产环境记得改成你的前端域名 CORS_ALLOW_ALL_ORIGINS = True
Angular 5前端实现
1. 定义表单数据模型
创建src/app/models/user-form.model.ts:
export interface UserForm { id_user_form?: number; // 可选,因为提交时后端会自动生成 user: number; // 注意:这里传的是User模型的ID,不是用户对象 name: string; type: string; location: string; }
2. 创建表单服务
创建src/app/services/form.service.ts:
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; import { UserForm } from '../models/user-form.model'; @Injectable({ providedIn: 'root' }) export class FormService { // 替换成你的DRF接口地址,比如http://localhost:8000/user-forms/ private apiUrl = 'http://your-drf-domain/user-forms/'; constructor(private http: HttpClient) { } submitUserForm(formData: UserForm): Observable<UserForm> { return this.http.post<UserForm>(this.apiUrl, formData); } }
3. 组件中实现表单提交
模板文件src/app/components/user-form/user-form.component.html
<form (ngSubmit)="onSubmit()" #userFormForm="ngForm"> <div> <label>用户ID:</label> <input type="number" name="user" [(ngModel)]="formData.user" required> </div> <div> <label>名称:</label> <input type="text" name="name" [(ngModel)]="formData.name" required> </div> <div> <label>类型:</label> <input type="text" name="type" [(ngModel)]="formData.type" required> </div> <div> <label>位置:</label> <input type="text" name="location" [(ngModel)]="formData.location" required> </div> <button type="submit" [disabled]="!userFormForm.valid">提交表单</button> </form>
组件逻辑src/app/components/user-form/user-form.component.ts
import { Component } from '@angular/core'; import { FormService } from '../../services/form.service'; import { UserForm } from '../../models/user-form.model'; @Component({ selector: 'app-user-form', templateUrl: './user-form.component.html', styleUrls: ['./user-form.component.css'] }) export class UserFormComponent { formData: UserForm = { user: 0, // 这里要替换成当前登录用户的ID,或者根据业务逻辑赋值 name: '', type: '', location: '' }; constructor(private formService: FormService) { } onSubmit(): void { this.formService.submitUserForm(this.formData).subscribe({ next: (response) => { console.log('表单提交成功!返回数据:', response); // 提交成功后可以重置表单 this.formData = { user: 0, name: '', type: '', location: '' }; }, error: (err) => { console.error('提交失败,错误信息:', err); // 这里可以给用户显示错误提示 } }); } }
4. 处理CSRF验证(如果DRF开启了CSRF)
DRF默认开启CSRF验证,Angular需要在请求中携带CSRF token,我们可以用拦截器自动处理:
创建src/app/interceptors/csrf.interceptor.ts:
import { HttpInterceptor, HttpRequest, HttpHandler } from '@angular/common/http'; import { Injectable } from '@angular/core'; @Injectable() export class CsrfInterceptor implements HttpInterceptor { intercept(req: HttpRequest<any>, next: HttpHandler) { // 从cookie中获取CSRF token const csrfToken = document.cookie.match(/csrftoken=([^;]+)/)?.[1]; if (csrfToken) { const modifiedReq = req.clone({ headers: req.headers.set('X-CSRFToken', csrfToken) }); return next.handle(modifiedReq); } return next.handle(req); } }
然后在app.module.ts中注册拦截器:
import { HTTP_INTERCEPTORS } from '@angular/common/http'; import { CsrfInterceptor } from './interceptors/csrf.interceptor'; @NgModule({ // ... 其他配置 providers: [ { provide: HTTP_INTERCEPTORS, useClass: CsrfInterceptor, multi: true } ] }) export class AppModule { }
关键注意事项
- 字段匹配:确保Angular发送的字段名和DRF序列化器的字段完全一致,比如
user字段必须传用户的ID,不能传用户对象。 - 错误排查:如果提交失败,打开浏览器控制台看网络请求的响应,DRF会返回详细的错误信息,比如必填字段缺失、字段类型错误等。
- 生产环境配置:生产环境不要用
CORS_ALLOW_ALL_ORIGINS = True,改成指定你的前端域名,比如CORS_ALLOWED_ORIGINS = ["https://your-frontend-domain.com"]。
内容的提问来源于stack exchange,提问作者Thanos Ganja
相关产品推荐
相关产品推荐

