我正在使用Django 2.0
和Django REST Framework
。
我在通讯录应用中有两个模型
联系人/模型.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
联系人/序列化器.py
class ContactPhoneNumberSerializer(serializers.ModelSerializer):
class Meta:
model = ContactPhoneNumber
fields = ('id', 'phone', 'primary', 'created', 'modified')
和联系人/views.py
class ContactPhoneNumberViewSet(viewsets.ModelViewSet):
serializer_class = ContactPhoneNumberSerializer
def get_queryset(self):
return ContactPhoneNumber.objects.filter(
contact__user=self.request.user
)
网址.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
我按照文档将ViewSets 明确地绑定到 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
url 使用明确的 url 绑定:
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),
]
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句