如何在路由器上注册单个视图(不是视图)? [英] How can I register a single view (not a viewset) on my router?
问题描述
我正在使用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屋!