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

Django Rest Framework中RetrieveUpdateDestroyAPIView的PUT方法失效问题

Hey there, let's walk through fixing your PUT request issue between Angular and Django Rest Framework's RetrieveUpdateDestroyAPIView. I’ve worked through this exact setup dozens of times, so here’s what to check and fix, along with properly formatted code examples and troubleshooting steps:

Troubleshooting PUT Requests with DRF's RetrieveUpdateDestroyAPIView & Angular

Common Error Scenarios You Might Be Seeing

First, let’s cover the most frequent errors and their quick fixes:

  • 403 Forbidden: Almost always a CSRF token issue (Angular isn’t sending the required header) or permission misconfiguration.
  • 400 Bad Request: Your serializer is rejecting the payload — missing required fields, invalid data types, or mismatched field names.
  • 404 Not Found: The URL in your Angular request doesn’t match the DRF endpoint (usually missing the object’s pk or a trailing slash).

Angular Side: PUT Request & Service Implementation

Here’s a properly structured example of your Angular component and service, with fixes for common pitfalls:

Component Code

import { Component } from '@angular/core';
import { ApiService } from './api.service';

@Component({
  selector: 'app-item-update',
  templateUrl: './item-update.component.html'
})
export class ItemUpdateComponent {
  // Example data matching your DRF serializer fields
  updatedItem = { id: 3, name: "Updated Widget", price: 29.99 };

  constructor(private apiService: ApiService) {}

  onUpdateItem() {
    this.apiService.updateItem(this.updatedItem.id, this.updatedItem).subscribe(
      (response) => console.log("Update succeeded!", response),
      (error) => console.error("Update failed:", error.error) // Log DRF's detailed error
    );
  }
}

API Service Code

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({ providedIn: 'root' })
export class ApiService {
  private baseApiUrl = "http://localhost:8000/api/items";

  constructor(private http: HttpClient) {}

  updateItem(itemId: number, itemData: any): Observable<any> {
    // Critical: Include the object's PK in the URL
    const endpoint = `${this.baseApiUrl}/${itemId}/`;
    // Set headers for JSON payload and CSRF token (for session auth)
    const headers = new HttpHeaders({
      'Content-Type': 'application/json',
      'X-CSRFToken': this.getCsrfToken()
    });

    return this.http.put(endpoint, itemData, { headers });
  }

  // Helper to grab CSRF token from Django's cookie
  private getCsrfToken(): string {
    return document.cookie
      .split('; ')
      .find(row => row.startsWith('csrftoken='))
      ?.split('=')[1] || '';
  }
}

Django Backend: URL & View Setup

Double-check your DRF configuration matches this:

URL Mapping (urls.py)

from django.urls import path
from .views import ItemDetailView

urlpatterns = [
    # The <int:pk> parameter is mandatory for RetrieveUpdateDestroyAPIView
    path('api/items/<int:pk>/', ItemDetailView.as_view(), name='item-detail'),
]

View Class (views.py)

from rest_framework.generics import RetrieveUpdateDestroyAPIView
from .models import Item
from .serializers import ItemSerializer

class ItemDetailView(RetrieveUpdateDestroyAPIView):
    queryset = Item.objects.all()
    serializer_class = ItemSerializer
    # Uncomment if using authentication/permissions
    # permission_classes = [IsAuthenticated]

Key Fixes & Verification Steps

  1. CSRF Token Handling: If you’re using DRF’s default session authentication, Angular must send the X-CSRFToken header. The service above handles this automatically by grabbing the token from Django’s cookie.
  2. Endpoint URL Accuracy: Ensure your Angular request includes the item’s pk and ends with a trailing slash (if your Django APPEND_SLASH setting is True, which it is by default).
  3. Serializer Validation: Test the PUT request directly using DRF’s browsable API. If it fails there, your serializer is the issue — check for required fields or custom validation rules.
  4. Payload Matching: Make sure the data sent from Angular exactly matches the fields in your DRF serializer. No extra fields (unless your serializer allows them with extra_kwargs={'*': {'required': False}}) and no missing required fields.
  5. Permissions: If you’re getting a 403, confirm your view’s permission_classes are set correctly and the authenticated user has permission to update the object.

内容的提问来源于stack exchange,提问作者amazing carrot soup

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 06:59:49