如何在路由器上注册单个视图(不是视图)? [英] How can I register a single view (not a viewset) on my router?

查看:123
本文介绍了如何在路由器上注册单个视图(不是视图)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using Django REST framework and have been trying to create a view that returns a small bit of information, as well as register it on my router.

I有四个模型存储信息,他们都有一个 created_time 字段。我想在一个视图中返回最近的对象(基于 created_time ),只有四个创建时间被返回。

I have four models which store information, and all of them have a created_time field. I am trying to make a view that returns the most recent objects (based on the created_time) in a single view, where only the four creation times are returned.

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

So, a possible JSON output from the view would look like

{
    "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根目录时,它与我的其他终端一起出现。

I am also hoping to register this view on my router, so it appears with the rest of my endpoints when the API root is loaded.

router.register(r'updatetime', views.UpdateTimeView)

这是我的四个模型我尝试使用

Here are the four models that I am trying to work with

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)

有可能吗?而且如何做?

Is it possible to do this? And how would it be done?

推荐答案

路由器工作 ViewSet ,并不是为普通视图设计的,但这并不意味着您不能使用他们有正常的看法。通常它们与模型(以及 ModelViewSet )一起使用,但是可以使用它们使用 GenericViewSet (if你通常会使用 GenericAPIView )和 ViewSet (如果你只是使用一个 APIView )。

Routers work with a ViewSet and aren't designed for normal views, but that doesn't mean that you cannot use them with a normal view. Normally they are used with models (and a ModelViewSet), but they can be used without them using the GenericViewSet (if you would normally use a GenericAPIView) and ViewSet (if you would just use an APIView).

对于列表视图,请求方法映射到 ViewSet 这个

For a list view, the request methods are mapped to ViewSet methods like this


  • GET - > list(self,request ,格式=无)

  • POST - > create(self, ,格式=无)

  • GET -> list(self, request, format=None)
  • POST- > create(self, request, format=None)

对于详细视图(在url中有一个主键),请求方法使用以下地图

For detail views (with a primary key in the url), the request methods use the following map


  • GET - > (self,request,pk,format = None)

  • PUT - > 更新(self,request,pk,format = None)

  • PATCH - > partial_update(self,request,pk,format = None)

  • DELETE - > destroy(self,request,pk,format = None)

  • GET -> retrieve(self, request, pk, format=None)
  • PUT -> update(self, request, pk, format=None)
  • PATCH -> partial_update(self, request, pk, format=None)
  • DELETE -> destroy(self, request, pk, format=None)

因此,如果您想在路由器上使用任何这些请求方法,您需要覆盖正确的视图方法(因此 list()而不是 get())。

So if you want to use any of these request methods with your view on your router, you need to override the correct view method (so list() instead of get()).

现在,具体在你的情况下你一般会使用看起来像

Now, specifically in your case you would have normally use an APIView that looked like

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,
        })

可比较的 ViewSet 将是

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,
        })

注意两个必要的更改: APIView - > ViewSet get - > 列表。我也更新了这个名字,表示它不仅仅是普通的视图(因为 ViewSet 不能以相同的方式初始化),但这不是必需的。

Notice the two required changes: APIView -> ViewSet and get -> list. I also updated the name to indicate that it was more than just a normal view (as a ViewSet cannot be initialized the same way), but that's not required.

所以使用这个新视图,你可以在路由器中注册它与其他任何一样。您需要一个 base_name ,因此可以生成url名称(通常会从查询器中拉出)。

So with this new view, you can just register it in the router the same way as any other. You need a base_name here so the url names can be generated (normally this would pull from the queryset).

router.register(r'updatetime', views.UpdateTimeViewSet, base_name='updatetime')

所以现在, updatetime 端点将在API根目录中可用,您可以通过调用端点来获取最新的时间(一个简单的GET请求)。

So now the updatetime endpoint will be made available in the API root and you can get the latest times by just calling the endpoint (a simple GET request).

这篇关于如何在路由器上注册单个视图(不是视图)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆