python - Django REST Framework - 在 URL 中添加 2 个 PK

标签 python django rest django-rest-framework

我正在为一个同时包含公司和部门的应用程序设计一个 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.pycompany应用程序。

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_fieldlookup_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/

相关文章:

Python索引错误: Out of bounds

Python/Pandas : Remove rows with outlying values, 保留所有列

django的collectstatic收集到意外的目录中

python - Django 字符串到日期格式

rest - API设计: Caching “partial” nested objects

php - 请求大量 Twitter API 数据、服务或操作方法?

rest - 如何整合Spring MVC和Nuxt JS?

python - 将函数映射和参数存储在字典中

python - Alpha Vantage "KeyError: ' 时间序列(每日 )'"

python - Django,属性错误: 'module' object has no attribute