如何在django rest框架中的一个URL端点执行crud操作?
目前我有2个url端点
url(r'^recipient/$', views.RecipientView.as_view()), # in this APiview im performing get all and post
url(r'^recipient/(?P<pk>[0-9]+)/$', views.RecipientDetail.as_view()), # in this APiview im performing retrieve, update delete.
现在要求是我删除第二个网址并在第一个api视图中执行所有操作?
我是django框架的新手可以有人帮我实现这个目标吗?
以下是我的代码。
View.py
class RecipientView(APIView):
def get(self, request, format=None):
Recipients = Recipient.objects.all()
serializer = RecipientSerializer(Recipients, many=True)
return Response(serializer.data)
def post(self, request, format=None):
serializer = RecipientSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
"""
class RecipientDetail(APIView):
def get_object(self, pk):
try:
return Recipient.objects.get(pk=pk)
except Recipient.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
Recipient = self.get_object(pk)
serializer = RecipientSerializer(Recipient)
return Response(serializer.data)
def put(self, request, pk, format=None):
Recipient = self.get_object(pk)
serializer = RecipientSerializer(Recipient, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk, format=None):
Recipient = self.get_object(pk)
Recipient.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
"""
model.py
class Recipient(models.Model):
recipient = models.CharField(max_length=32, blank=False, null=False)
def __str__(self):
"""returns the model as string."""
return self.racipi
耳鼻喉科
serializer.py
class RecipientSerializer(serializers.ModelSerializer):
class Meta:
model = Recipient
fields = '__all__'
我无法在同一视图中更新和删除,需要帮助吗?
答案 0 :(得分:0)
您的第二个URL正在接收一个参数,可用于从数据库中获取数据对象,然后对该特定实例执行任何操作。如果您看到类RecipientDetail
,则会看到所有方法都接受名为pk
的参数,该参数与您要从数据库中提取的对象相关。
但您的第一个网址适用于Create New Object
或List All Objects
等通用操作,并且使用这些端点执行特定于实例的操作并不好。
您可以阅读有关REST API标准enpoints的更多信息,以了解详细信息。以下是参考链接:
https://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api
答案 1 :(得分:0)
您可以避免使用POST请求在URL中传递ID。提供ID和某种&#34;动作&#34;动词,例如请求正文中的action=delete
。
这不被认为是RESTful,部分原因是HTTP DELETE和PUT动词完美地描述了所请求的操作,但也因为POST被认为是非幂等方法,这意味着服务器状态将随着每个成功的请求而改变。作为幂等,重复的DELETE / PUT(以及GET)请求将使服务器处于相同的状态。
拥有第二条路径以及实现REST API的观点并不是一件很麻烦的事情,因此最好保持原样。
答案 2 :(得分:0)
最简单的方法是使用DRF的ViewSet。它已经为您提供了基本的CRUD操作,因此您可以使用以下内容创建视图:
# views.py
from rest_framework import viewsets
from .models import Recipient
from .serializers import RecipientSerializer
class RecipientViewSet(viewsets.ModelViewSet):
"""
A viewset for viewing and editing recipient instances.
"""
serializer_class = RecipientSerializer
queryset = Recipient.objects.all()
由于我们使用的是ModelViewSet,它已经提供了get,list,update等操作,正如您在documentation中看到的那样。
然后,您可以在urls.py中使用routers,如下所示:
# urls.py
from rest_framework.routers import DefaultRouter
from myapp.views import RecipientViewSet
router = DefaultRouter()
router.register(r'recipients', RecipientViewSet)
urlpatterns = router.urls
上面的网址会生成一个网址,就像你在问题中写的那样:
# Add recipient
POST /recipients/
# Get list of recipients
GET /recipients/
# Get recipient detail
GET /recipients/:recipient_id/
# Update recipient
PUT/PATCH /recipients/:recipient_id/
# Delete recipient
DELETE /recipients/:recipient_id/
请注意,这是一个简化版本,您甚至可以使用指定的操作创建自己的网址模式。
<强>更新强>
感谢mhawke的澄清。正如mhawke在评论中所说,这可能不是OP想要的,如果你只是想避免在网址中传递ID,那么你可以按照mawke的回答,是的,它不被认为是RESTful。