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

Angular 13调用DRF删除接口异常:delete方法最后一行未执行

Angular 13 结合 Django REST Framework 删除对象失败排查与修复

问题描述

通过Angular 13删除DRF关联数据库中的对象时,已确认获取到正确的待删除ID,但service.ts中delete方法的最后一行HTTP DELETE代码未执行。

现有代码片段

COMPONENT.HTML

<li *ngFor="let source of sources$ | async | filter: filterTerm">
       <div class="card">
        <div class="card-body">
          <h5 class="card-title">{{source.name}}</h5>
          <p>URL:- <a href='{{source.url}}'>{{source.url}}</a></p>
          <a class="btn btn-primary" href='fetch/{{source.id}}' role="button">fetch</a>

           <button class="btn btn-primary" (click)="deleteSource(source.id)">delete </button>
           <br>
        </div>
            </div>
</li>

component.ts

export class SourcesComponent implements OnInit {
  filterTerm!: string;
  sources$ !: Observable<sources[]>;

  constructor(private sourcesService: SourcesService) { }

  ngOnInit(): void {
    this.Source();
  }

  Source(){
    this.sources$ = this.sourcesService.Sources()
      }

  deleteSource(id : string){
  console.log(id)
    this.sourcesService.deleteSource(id);
    }
}

service.ts

export class SourcesService {
API_URL = 'http://127.0.0.1:8000/sourceapi';

constructor(private http: HttpClient) { }

     /** GET sources from the server */
    Sources() :  Observable<sources[]> {
      return this.http.get<sources[]>(this.API_URL);
    }

    /** POST: add a new source to the server */
    addSource(source : sources[]): Observable<sources[]>{
      return this.http.post<sources[]> (this.API_URL, source);
      }

    deleteSource(id: string): Observable<number>{
    let httpheaders=new HttpHeaders()
    .set('Content-type','application/Json');
    let options={
      headers:httpheaders
    };
     console.log(id)
     return this.http.delete<number>(this.API_URL +'/'+id)
  }
}

修复方案

1. 触发Observable订阅(核心问题)

Angular的HttpClient返回的是冷Observable,只有订阅后才会发起实际HTTP请求。修改component.ts中的deleteSource方法:

deleteSource(id : string){
  console.log(id);
  this.sourcesService.deleteSource(id).subscribe({
    next: () => {
      // 删除成功后刷新数据源,更新页面展示
      this.Source();
    },
    error: (error) => {
      console.error('删除请求失败:', error);
    }
  });
}

2. 添加DRF CSRF令牌验证

DRF默认启用CSRF保护,未携带令牌的请求会被拒绝。步骤如下:

  • 安装Cookie服务依赖:
npm install ngx-cookie-service
  • 在service.ts中导入并配置CSRF令牌:
import { CookieService } from 'ngx-cookie-service';

export class SourcesService {
  API_URL = 'http://127.0.0.1:8000/sourceapi';

  constructor(private http: HttpClient, private cookieService: CookieService) { }

  deleteSource(id: string): Observable<any>{
    const csrfToken = this.cookieService.get('csrftoken');
    const httpheaders = new HttpHeaders()
      .set('Content-type', 'application/json')
      .set('X-CSRFToken', csrfToken);
    
    console.log(id);
    return this.http.delete(`${this.API_URL}/${id}`, { headers: httpheaders });
  }
}
  • 在AppModule中注册CookieService:
import { CookieService } from 'ngx-cookie-service';

@NgModule({
  providers: [CookieService],
  // ...其他配置
})
export class AppModule { }

3. 验证DRF路由配置

确保DRF的urls.py中存在带主键的DELETE路由,比如使用视图集:

from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import SourceViewSet

router = DefaultRouter()
router.register(r'sourceapi', SourceViewSet, basename='source')

urlpatterns = [
    path('', include(router.urls)),
]

或者手动配置详情路由:

path('sourceapi/<int:pk>/', SourceDetailView.as_view(), name='source-detail')

4. 类型匹配调整

如果DRF返回的不是数字类型,建议将service.ts中deleteSource的返回类型改为Observable<any>或对应的数据类型,避免类型不匹配问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 04:55:17