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
相关产品推荐
相关产品推荐

