Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在路由器上注册单个视图(不是视图集)?_Python_Django_Django Rest Framework - Fatal编程技术网

Python 如何在路由器上注册单个视图(不是视图集)?

Python 如何在路由器上注册单个视图(不是视图集)?,python,django,django-rest-framework,Python,Django,Django Rest Framework,我正在使用Django REST框架,并且一直在尝试创建一个返回少量信息的视图,并在我的路由器上注册它 我有四个存储信息的模型,它们都有一个created\u time字段。我试图创建一个视图,在单个视图中返回最新的对象(基于创建时间),其中只返回四个创建时间 因此,视图中可能的JSON输出如下所示 { "publish_updatetime": "2015.05.20 11:53", "meeting_updatetime": "2015.05.20 11:32", "

我正在使用Django REST框架,并且一直在尝试创建一个返回少量信息的视图,并在我的路由器上注册它

我有四个存储信息的模型,它们都有一个
created\u time
字段。我试图创建一个视图,在单个视图中返回最新的对象(基于
创建时间
),其中只返回四个创建时间

因此,视图中可能的JSON输出如下所示

{
    "publish_updatetime": "2015.05.20 11:53",
    "meeting_updatetime": "2015.05.20 11:32",
    "training_updatetime": "2015.05.20 15:25",
    "exhibiting_updatetime": "2015.05.19 16:23"
}
我还希望在我的路由器上注册这个视图,这样当加载API根目录时,它就会出现在我的其余端点上

router.register(r'updatetime', views.UpdateTimeView)
以下是我尝试使用的四种模型

class Publish(models.Model):
    user = models.ForeignKey(MyUser)
    name = models.CharField(max_length=50)
    created_time = models.DateTimeField( default=datetime.now)

class Meeting(models.Model):
    user = models.ForeignKey(MyUser)
    name = models.CharField(max_length=50)
    file_addr = models.FileField(upload_to=get_file_path)
    created_time = models.DateTimeField(default=datetime.now)

class Training(models.Model):
    user = models.ForeignKey(MyUser)
    name = models.CharField(max_length=50)
    image = models.ImageField(upload_to=get_file_path, max_length=255)
    created_time = models.DateTimeField(default=datetime.now)

class Exhibiting(models.Model):
    user = models.ForeignKey(MyUser)
    name = models.CharField(max_length=50)
    file_addr = models.FileField(upload_to=get_file_path)
    created_time = models.DateTimeField(default=datetime.now)
有可能这样做吗?怎么做呢?

路由器可以工作,并且不是为普通视图设计的,但这并不意味着你不能在普通视图中使用它们。通常,它们与模型一起使用(以及
ModelViewSet
),但是它们可以在不使用它们的情况下使用
GenericViewSet
(如果您通常使用
GenericAPIView
)和
ViewSet
(如果您只使用
apiew

对于列表视图,请求方法映射到如下方法

  • GET
    ->
    列表(self,request,format=None)
  • POST
    ->
    create(self,request,format=None)
对于细节视图(url中有主键),请求方法使用以下映射

  • GET
    ->
    retrieve(self,request,pk,format=None)
  • PUT
    ->
    更新(self,request,pk,format=None)
  • 补丁
    ->
    部分更新(self、request、pk、format=None)
  • 删除
    ->
    销毁(self,request,pk,format=None)
因此,如果您想在路由器上的视图中使用这些请求方法中的任何一种,您需要覆盖正确的视图方法(因此
list()
而不是
get()


现在,特别是在您的情况下,您通常会使用

class UpdateTimeView(APIView):

    def get(self, request, format=None):
        latest_publish = Publish.objects.latest('created_time')
        latest_meeting = Meeting.objects.latest('created_time')
        latest_training = Training.objects.latest('created_time')
        latest_exhibiting = Exhibiting.objects.latest('created_time')

        return Response({
            "publish_updatetime": latest_publish.created_time,
            "meeting_updatetime": latest_meeting.created_time,
            "training_updatetime": latest_training.created_time,
            "exhibiting_updatetime": latest_exhibiting.created_time,
        })
可比较的
视图集将是

class UpdateTimeViewSet(ViewSet):

    def list(self, request, format=None):
        latest_publish = Publish.objects.latest('created_time')
        latest_meeting = Meeting.objects.latest('created_time')
        latest_training = Training.objects.latest('created_time')
        latest_exhibiting = Exhibiting.objects.latest('created_time')

        return Response({
            "publish_updatetime": latest_publish.created_time,
            "meeting_updatetime": latest_meeting.created_time,
            "training_updatetime": latest_training.created_time,
            "exhibiting_updatetime": latest_exhibiting.created_time,
        })
请注意两个必需的更改:
apieview
->
ViewSet
get
->
列表
。我还更新了名称,表明它不仅仅是一个普通视图(因为
ViewSet
不能以相同的方式初始化),但这不是必需的

因此,有了这个新视图,您可以像其他视图一样在路由器中注册它。这里需要一个
base\u名称
,这样就可以生成url名称(通常这将从queryset中提取)


因此现在,
updatetime
端点将在API根目录中可用,您只需调用端点(一个简单的get请求)即可获得最新时间。

还有一种方法:

urlpatterns = [
    # ... 
    url(r'^you_path/', include(router.urls)),
    url(r'^you_path/you_sub_path', views.UpdateTimeView.as_view()),
    # ... 
]

但是像Swagger这样的东西是不适用的

你有没有任何视图、序列化程序或模型可以包含在你的问题中?你的主要问题是什么也不完全清楚,因为这里没有太多的工作要做。嗨,凯文,我已经添加了所有的模型和序列化程序。如何使用ViewSet处理此问题,并使用“路由器”注册url。谢谢目前还不清楚所有这些模型应该如何分组。很明显,这不是由时间创建的(这将导致它们都是相同的)。这四个模型应该如何检索?在视图中通常如何执行?只需返回这四个模型的最新创建时间。返回的json包括4个层次:发布更新时间->发布创建时间,会议更新时间->会议创建时间,培训更新时间->培训创建时间,展示更新时间->展示创建时间。我们可以得到最新的创建时间,比如:Publish.objects.latest('created_time')。很好,所有这些都是应该首先包含的信息。现在我意识到,您的问题更接近于“我如何拥有一个只返回列表方法的视图集”,而不是“我如何将多个模型聚合为一个响应”。因此,不可能在
路由器中注册
APIView
?我的情况是,我想公开几个不适用于具体资源(定义为Django模型)的API,我还想将它们放在一个视图集中,并在特定url前缀下公开它们,例如
scheduler/get\u job
scheduler/report\u result
,等等。你的解决方案如何应用于这个案例?@ChenxiongQi我有一个确切的问题-你找到答案了吗?在这些案例中,你可以使用
@list\u route
装饰器@dkhaupt@ChenxiongQi只是想注意,你应该使用
from rest\u framework import ViewSet.ViewSet
来使用它。
urlpatterns = [
    # ... 
    url(r'^you_path/', include(router.urls)),
    url(r'^you_path/you_sub_path', views.UpdateTimeView.as_view()),
    # ... 
]