[英]How to add Q lookups with the get_queryset in Django rest framework?
[英]add parameter to get_queryset request in Django REST Framework
我正在使用Django 2.0
和Django 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')
我想要的是端點
/contact-phone/{contact_id}/
列出特定聯系人的電話號碼 /contact-phone/{contact_id}/
為特定聯系人添加電話號碼 /contact-phone/{contact_phone_number_id}/
更新特定的電話號碼 /contact-phone/{contact_phone_number_id}/
刪除特定的電話號碼 PUT
和Delete
可以實現作為默認操作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
由於不需要其他操作,因此可以覆蓋retrieve
和create
默認方法:
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.