Django-REST:添加 API 以通过另一个字段获取实体的正确方法?
Django-REST: Proper way to add API to get entity via another field?
我是 Python/Django/Django-REST 的超级新手,但我已经设法遵循 tutorial 并创建了我自己的 API,类似于教程。
在我的应用程序中,我有一个名为 Toggle
的模型,其中有一个名为 feature_key
.
的唯一字段
按照教程,获取 Toggle
的默认方法是使用 ID,即
http://127.0.0.1:8000/toggles/1/
它在可浏览的 API 页面中显示为可点击的 link。
我的问题是,如何添加另一个端点以通过其 feature_key
直接获得切换?也许是这样的:
http://127.0.0.1:8000/toggles/key/category.key_1/
(我不确定这是不是"correct"设计的方式API)
如何使此端点在可浏览的 API 中可见,以便其他开发人员知道此端点存在?
toggle/views.py
:
这几乎和教程的一样view.py
# imports here
@api_view(['GET'])
def api_root(request, format=None):
return Response({
'users': reverse('user-list', request=request, format=format),
'toggles': reverse('toggle-list', request=request, format=format)
})
class ToggleViewSet(viewsets.ModelViewSet):
queryset = Toggle.objects.all()
serializer_class = ToggleSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly]
def perform_create(self, serializer):
serializer.save(created_by=self.request.user)
class UserViewSet(viewsets.ReadOnlyModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
toggle/serializers.py
:
也类似教程
class ToggleSerializer(serializers.HyperlinkedModelSerializer):
created_by = serializers.ReadOnlyField(source='created_by.username')
is_enabled = serializers.BooleanField(initial=True)
class Meta:
model = Toggle
fields = ['url', 'id', 'feature_key', 'description', 'is_enabled', 'created_at', 'created_by']
class UserSerializer(serializers.HyperlinkedModelSerializer):
toggles = serializers.HyperlinkedRelatedField(many=True, view_name='toggle-detail', read_only=True)
class Meta:
model = User
fields = ['url', 'id', 'username', 'toggles']
toggle/urls.py
:
与教程相同
router = DefaultRouter()
router.register(r'toggles', views.ToggleViewSet)
router.register(r'users', views.UserViewSet)
urlpatterns = [
path('', include(router.urls)),
]
我看了教程...
您可以进行以下更改:
urls.py
替换这个
path('toggles/<int:pk>/', views.toggles_function),
有了这个:
path('toggles/<feature_key>/', views.toggles_function),
views.py
@csrf_exempt
def snippet_detail(request, key):
try:
snippet = Snippet.objects.get(feature_key=key)
except Snippet.DoesNotExist:
return HttpResponse(status=404)
你可以获得linkhttp://127.0.0.1:8000/toggles/<feature_key of entry>/
如果你想要link这样
http://127.0.0.1:8000/toggles/key/category.key_1/
在urls.py
path('toggles/<pk>/<feature_key>/', views.toggles_function),
并在 views.py
@csrf_exempt
def snippet_detail(request, pk, key):
try:
snippet = Snippet.objects.get(feature_key=key) # snippet = Snippet.objects.get(pk=pk)
except Snippet.DoesNotExist:
return HttpResponse(status=404)
建议
您不需要在 url 中使用来自同一模型的两个字段(如 pk 和 feature_key 两者),如果它们都是唯一字段。您可以从其中任何一个获取实例。
我是 Python/Django/Django-REST 的超级新手,但我已经设法遵循 tutorial 并创建了我自己的 API,类似于教程。
在我的应用程序中,我有一个名为 Toggle
的模型,其中有一个名为 feature_key
.
按照教程,获取 Toggle
的默认方法是使用 ID,即
http://127.0.0.1:8000/toggles/1/
它在可浏览的 API 页面中显示为可点击的 link。
我的问题是,如何添加另一个端点以通过其 feature_key
直接获得切换?也许是这样的:
http://127.0.0.1:8000/toggles/key/category.key_1/
(我不确定这是不是"correct"设计的方式API)
如何使此端点在可浏览的 API 中可见,以便其他开发人员知道此端点存在?
toggle/views.py
:
这几乎和教程的一样view.py
# imports here
@api_view(['GET'])
def api_root(request, format=None):
return Response({
'users': reverse('user-list', request=request, format=format),
'toggles': reverse('toggle-list', request=request, format=format)
})
class ToggleViewSet(viewsets.ModelViewSet):
queryset = Toggle.objects.all()
serializer_class = ToggleSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly]
def perform_create(self, serializer):
serializer.save(created_by=self.request.user)
class UserViewSet(viewsets.ReadOnlyModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
toggle/serializers.py
:
也类似教程
class ToggleSerializer(serializers.HyperlinkedModelSerializer):
created_by = serializers.ReadOnlyField(source='created_by.username')
is_enabled = serializers.BooleanField(initial=True)
class Meta:
model = Toggle
fields = ['url', 'id', 'feature_key', 'description', 'is_enabled', 'created_at', 'created_by']
class UserSerializer(serializers.HyperlinkedModelSerializer):
toggles = serializers.HyperlinkedRelatedField(many=True, view_name='toggle-detail', read_only=True)
class Meta:
model = User
fields = ['url', 'id', 'username', 'toggles']
toggle/urls.py
:
与教程相同
router = DefaultRouter()
router.register(r'toggles', views.ToggleViewSet)
router.register(r'users', views.UserViewSet)
urlpatterns = [
path('', include(router.urls)),
]
我看了教程...
您可以进行以下更改: urls.py
替换这个
path('toggles/<int:pk>/', views.toggles_function),
有了这个:
path('toggles/<feature_key>/', views.toggles_function),
views.py
@csrf_exempt
def snippet_detail(request, key):
try:
snippet = Snippet.objects.get(feature_key=key)
except Snippet.DoesNotExist:
return HttpResponse(status=404)
你可以获得linkhttp://127.0.0.1:8000/toggles/<feature_key of entry>/
如果你想要link这样
http://127.0.0.1:8000/toggles/key/category.key_1/
在urls.py
path('toggles/<pk>/<feature_key>/', views.toggles_function),
并在 views.py
@csrf_exempt
def snippet_detail(request, pk, key):
try:
snippet = Snippet.objects.get(feature_key=key) # snippet = Snippet.objects.get(pk=pk)
except Snippet.DoesNotExist:
return HttpResponse(status=404)
建议
您不需要在 url 中使用来自同一模型的两个字段(如 pk 和 feature_key 两者),如果它们都是唯一字段。您可以从其中任何一个获取实例。