簡體   English   中英

在Django REST Framework中向get_queryset請求添加參數

[英]add parameter to get_queryset request in Django REST Framework

我正在使用Django 2.0Django REST Framework

我在通訊錄應用中有兩個模型

聯系人/ models.py

class Contact(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100, blank=True, null=True, default='')


class ContactPhoneNumber(models.Model):
    contact = models.ForeignKey(Contact, on_delete=models.CASCADE)
    phone = models.CharField(max_length=100)
    primary = models.BooleanField(default=False)

    def __str__(self):
        return self.phone

聯系人/ serializers.py

class ContactPhoneNumberSerializer(serializers.ModelSerializer):
    class Meta:
        model = ContactPhoneNumber
        fields = ('id', 'phone', 'primary', 'created', 'modified')

contact / views.py

class ContactPhoneNumberViewSet(viewsets.ModelViewSet):
    serializer_class = ContactPhoneNumberSerializer

    def get_queryset(self):
        return ContactPhoneNumber.objects.filter(
            contact__user=self.request.user
        )

urls.py

router.register(r'contact-phone', ContactPhoneNumberViewSet, 'contact_phone_numbers')

我想要的是端點

  • GET: /contact-phone/{contact_id}/ 列出特定聯系人的電話號碼
  • POST: /contact-phone/{contact_id}/ 為特定聯系人添加電話號碼
  • PUT: /contact-phone/{contact_phone_number_id}/ 更新特定的電話號碼
  • 刪除: /contact-phone/{contact_phone_number_id}/ 刪除特定的電話號碼

PUTDelete可以實現作為默認操作ModelViewSet但如何讓get_queryset接受contact_id所需的參數?

編輯2

我按照文檔將ViewSet明確綁定到URL

更新app / urls.py

router = routers.DefaultRouter()
router.register(r'contacts', ContactViewSet, 'contacts')
contact_phone_number_view_set = ContactPhoneNumberViewSet.as_view({
    'get': 'list/<contact_pk>/',
    'post': 'create/<contact_pk>/',
    'put': 'update',
    'delete': 'destroy'
})
router.register(r'contact-phone-number', contact_phone_number_view_set, 'contact_phone_numbers')

urlpatterns = [
    path('api/', include(router.urls)),
    url(r'^admin/', admin.site.urls),
]

但這給了錯誤

AttributeError: 'function' object has no attribute 'get_extra_actions'

您可以使用@action裝飾器向視圖集添加其他操作:

class ContactPhoneNumberViewSet(viewsets.ModelViewSet):
    serializer_class = ContactPhoneNumberSerializer

    def get_queryset(self):
        return ContactPhoneNumber.objects.filter(
            contact__user=self.request.user
        )

    @action(methods=['post'], detail=False)
    def add_to_contact(self, request, contact_id=None):
        contact = Contact.objects.get(id=contact_id)
        serializer = ContactPhoneNumberSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save(contact=contact)
            return Response(serializer.data)
        else:
            return Response(serializer.errors,
                            status=status.HTTP_400_BAD_REQUEST)

    @action(methods=['get'], detail=False)
    def set_password(self, request, contact_id=None):
        contact = Contact.objects.get(id=contact_id)
        serializer = PasswordSerializer(contact.contactphonenumber_set.all(), many=True)
        return Response(serializer.data)

UPD

由於不需要其他操作,因此可以覆蓋retrievecreate默認方法:

class ContactPhoneNumberViewSet(viewsets.ModelViewSet):
        serializer_class = ContactPhoneNumberSerializer

        def get_queryset(self):
            return ContactPhoneNumber.objects.filter(
                contact__user=self.request.user
            )

        def create(self, request, pk=None):
            contact = Contact.objects.get(id=contact_id)
            serializer = ContactPhoneNumberSerializer(data=request.data)
            if serializer.is_valid():
                serializer.save(contact=contact)
                return Response(serializer.data)
            else:
                return Response(serializer.errors,
                                status=status.HTTP_400_BAD_REQUEST)

        def retrieve(self, request, pk=None):
            contact = Contact.objects.get(pk=pk)
            serializer = PasswordSerializer(contact.contactphonenumber_set.all(), many=True)
            return Response(serializer.data)

要更改標准create網址,請使用明確的網址綁定:

contact_list = ContactPhoneNumberViewSet.as_view({
    'get': 'list',
    'post': 'create',
    'put': 'update',
    'delete': 'destroy'
})

urlpatterns = [
    path('api//contact-phone/<int:pk>/', contact_list, name='contact-list'),
    url(r'^admin/', admin.site.urls),
]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM