我正在为一个同时包含公司和部门的应用程序设计一个 REST API。一定数量的用户可以是公司的成员。这导致了以下 API 结构:
/companies/
- 可以获取、发布。
/companies/<pk>/
- 可以获取、发布、发布、修补、删除。
/companies/<pk>/membership/
- 可以 GET(为公司成员的所有用户提供)、POST。
/companies/<pk>/membership/<pk>/
- 可以删除。
我已经成功实现了前 3 个端点,但在实现最后一个端点时遇到了麻烦 - 如何实现具有多个 <pk>
的端点URL 中的值?这是我到目前为止所拥有的:
目前api
中有一个urls.py文件应用程序如下所示:
...
url(r'^company', include(company_urls.company_router.urls,
namespace="company")),
...
urls.py
在 company
应用程序。
from rest_framework import routers
from .views import CompanyViewSet
company_router = routers.DefaultRouter()
company_router.register(r'^', CompanyViewSet)
serializers.py 文件:
from rest_framework import serializers
from .models import Company, CompanyMembership
from My_App.users.models import Profile
class CompanySerializer(serializers.ModelSerializer):
class Meta:
model = Company
fields = ('pk', 'name', 'departments', 'members')
read_only_fields = ('pk', 'departments', 'members')
class CompanyMembershipSerializer(serializers.Serializer):
user = serializers.PrimaryKeyRelatedField(queryset=Profile.objects.all())
def create(self, validated_data):
pass
def delete(self, instance, validated_data):
pass
还有views.py文件:
from .models import Company, CompanyMembership
from .serializers import CompanySerializer, CompanyMembershipSerializer
from My_Appc.users.models import Profile
class CompanyViewSet(viewsets.ModelViewSet):
queryset = Company.objects.all()
serializer_class = CompanySerializer
@decorators.detail_route(methods=['get', 'post', 'delete'])
def membership(self, request, pk):
company = self.get_object()
if request.method == 'GET':
serializer = CompanyMembershipSerializer(company)
elif request.method == 'POST':
serializer = CompanyMembershipSerializer(data=request.data)
if serializer.is_valid():
try:
user = Profile.objects.get(pk=request.data.get('user'))
user_company_membership = CompanyMembership(user=user,
company=company)
user_company_membership.save()
return Response({'status': 'User added to Company.'},
status=status.HTTP_201_CREATED)
except IntegrityError:
result = {
'status': 'Failed to add user to Company.',
'reason': 'User already part of Company.'
}
status=settings.ADDITIONAL_HTTP_STATUS_CODES[
'422_UNPROCESSABLE_ENTITY']
return Response(result, status)
else:
return Response(serializer.errors,
status=status.HTTP_400_BAD_REQUEST)
最佳答案
对 URL 中的参数使用不同的名称:
/companies/<company_pk>/membership/<membership_pk>/
并在 ViewSet 中添加 lookup_field
和 lookup_url_kwarg
以指向公司 pk 字段/参数:
class CompanyViewSet(viewsets.ModelViewSet):
lookup_field = 'pk'
lookup_url_kwarg = 'company_pk'
get_object
方法使用这两个查找来过滤查询集,这样您就可以根据 url 中的第一个 pk 获取公司。
在您的成员(member)资格方法和管理成员(member)资格对象的自定义逻辑中,您可以通过以下方式访问成员(member)资格 pk:
membership_pk = self.kwargs.get('membership_pk', None)
关于python - Django REST Framework - 在 URL 中添加 2 个 PK,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37611248/