如何在Django Rest Framework类视图中通过slug而非ID获取详情页
如何在Django Rest Framework中通过Slug访问详情API端点
我正在使用Django Rest Framework构建API,现有/api/localities端点用于展示数据库中的所有地区对象。现在想创建单个地区的详情端点,要求通过slug而非ID访问,例如/api/localities/munich。目前使用类视图只能通过ID(如/api/localities/2)获取详情页,请问如何修改为使用slug?
以下是我的代码:
models.py
class Localities(models.Model): id_from_api = models.IntegerField() city = models.CharField(max_length=255, null=True, blank=True) slug = models.CharField(max_length=255, null=True, blank=True) postal_code = models.CharField(max_length=20, null=True, blank=True) country_code = models.CharField(max_length=10, null=True, blank=True) lat = models.CharField(max_length=255, null=True, blank=True) lng = models.CharField(max_length=255, null=True, blank=True) google_places_id = models.CharField(max_length=255, null=True, blank=True) search_description = models.CharField(max_length=500, null=True, blank=True) seo_title = models.CharField(max_length=255, null=True, blank=True) def __str__(self): return self.city
serializers.py
from rest_framework import serializers from .models import Localities class LocalitiesSerializers(serializers.ModelSerializer): class Meta: model = Localities fields = ( "id", "id_from_api", "city", "slug", "postal_code", "country_code", "lat", "lng", "google_places_id", "search_description", "seo_title", )
views.py
from django.shortcuts import render from django.http import HttpResponse from wagtail.core.models import Page from .models import LocalityPage, Localities from django.core.exceptions import ObjectDoesNotExist from rest_framework import generics import json import requests from .models import Localities from .serializers import LocalitiesSerializers class LocalitiesAll(generics.ListCreateAPIView): queryset = Localities.objects.all() serializer_class = LocalitiesSerializers class LocalitiesDetail(generics.RetrieveUpdateDestroyAPIView): queryset = Localities.objects.all() serializer_class = LocalitiesSerializers
urls.py
from django.urls import path from . import views urlpatterns = [ path('reload', views.convert_json), # app homepage path("localities/", views.LocalitiesAll.as_view()), path("localities/<int:pk>/", views.LocalitiesDetail.as_view()), ]
修改步骤
1. 优化Slug字段(可选但强烈推荐)
当前slug字段允许为空和重复,这会导致通过slug查询时可能找不到对象或返回多个对象。建议将其修改为唯一、非空的SlugField:
# models.py slug = models.SlugField(max_length=255, unique=True, null=False, blank=False)
注:
SlugField会自动处理字符串格式(转小写、替换特殊字符为横杠),如果需要保留原有格式,也可以继续用CharField但必须添加unique=True约束。
2. 配置视图使用Slug查询
在LocalitiesDetail视图类中添加lookup_field属性,指定用slug字段作为查询依据:
# views.py class LocalitiesDetail(generics.RetrieveUpdateDestroyAPIView): queryset = Localities.objects.all() serializer_class = LocalitiesSerializers lookup_field = 'slug' # 核心修改:用slug替代默认的pk
3. 更新URL路由
将URL中的<int:pk>替换为<slug:slug>(如果是普通CharField可以用<str:slug>),匹配slug格式的参数:
# urls.py urlpatterns = [ path('reload', views.convert_json), # app homepage path("localities/", views.LocalitiesAll.as_view()), path("localities/<slug:slug>/", views.LocalitiesDetail.as_view()), # 修改此处 ]
内容的提问来源于stack exchange,提问作者Blerdijan
相关产品推荐
相关产品推荐

