Python 在同一Api视图中更新和删除,而不在Url中传递id

Python 在同一Api视图中更新和删除,而不在Url中传递id,python,django,django-rest-framework,Python,Django,Django Rest Framework,如何在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 perf

如何在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.
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
耳鼻喉科

序列化程序.py

class RecipientSerializer(serializers.ModelSerializer):

    class Meta:
        model = Recipient
        fields = '__all__'

我无法在同一视图中更新和删除。是否需要帮助?

您的第二个URL正在接收一个参数,该参数可用于从数据库获取数据对象,然后对该特定实例执行任何操作。如果您看到类
RecipientDetail
,您将看到所有方法都在接受一个名为
pk
的参数,该参数与您要从数据库获取的对象相关

但是您的第一个URL用于一般操作,如
创建新对象
列出所有对象
,使用这些端点执行特定于实例的操作并不好

您可以阅读有关RESTAPI标准enpoints的更多信息以了解详细信息。以下是一个参考链接:


您可以避免通过POST请求在URL中传递ID。在请求主体中提供ID和某种“动作”动词,例如
action=delete

但这并不被认为是RESTful的,部分原因是HTTP DELETE和PUT动词完美地描述了请求的操作,还因为POST被认为是非幂等方法,这意味着服务器状态将随着每个成功请求而改变。由于是幂等的,重复的DELETE/PUT(和GET)请求将使服务器保持相同的状态


使用第二个路由和视图来实现RESTAPI并不是什么大麻烦,所以最好保持原样。

最简单的方法是使用DRF。它已经为您提供了基本的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()
# urls.py
from rest_framework.routers import DefaultRouter

from myapp.views import RecipientViewSet

router = DefaultRouter()
router.register(r'recipients', RecipientViewSet)
urlpatterns = router.urls
因为我们使用的是ModelViewSet,所以它已经提供了诸如get、list、update等操作,您可以在中看到

然后,您可以在URL.py中使用以下内容:

# 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()
# urls.py
from rest_framework.routers import DefaultRouter

from myapp.views import RecipientViewSet

router = DefaultRouter()
router.register(r'recipients', RecipientViewSet)
urlpatterns = router.urls
上面的url将生成一个类似于您在问题中所写的url:

# 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/
请注意,这是一个简化版本,您甚至可以使用指定的操作创建自己的URL模式

更新:


感谢mhawke的澄清。正如mhawke在评论中所说的,这可能不是OP想要的,如果您只是想避免在url中传递ID,那么您可以按照mawke的回答,是的,它不被视为RESTful。

您将如何指定要更新/删除的对象?第二个端点正是为了提供对象pk而设计的。为什么要删除第二个路由?嗨,伙计们,上面的代码对于所有crud操作都非常有效。请告知在DRF中选择api端点的最佳方式。我的前辈建议我使用2个url端点不是最佳实践。所以我需要在一个url中执行所有操作。这很好,但它仍然需要多个路由,我认为OP出于某些未指明的原因正在试图避免。啊,是的,似乎我误解了这个问题,我只是认为他希望两个操作只有一个视图。有一个视图处理CRUD是一种改进,尤其是代码太少了。路由由一个定义生成也很好。也许OP会解释他们的动机。