如何在路由器上注册单个视图(不是视图集)?
How can I register a single view (not a viewset) on my router?
我正在使用 Django REST 框架,并一直在尝试创建一个包含 returns 少量信息的视图,并将其注册到我的路由器上。
我有四个存储信息的模型,它们都有一个 created_time
字段。我试图在单个视图中创建 returns 最近对象(基于 created_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 root 时它会出现在我的其他端点上。
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)
这可以吗?以及如何完成?
路由器工作 with a ViewSet
并且不是为普通视图设计的,但这并不意味着您不能在普通视图中使用它们。通常它们与模型一起使用(和 ModelViewSet
),但它们可以在没有它们的情况下使用 GenericViewSet
(如果您通常使用 GenericAPIView
)和 ViewSet
(如果你只想使用 APIView
).
对于列表视图,请求方法映射到 ViewSet
方法,如下所示
GET
-> list(self, request, format=None)
POST
- > create(self, request, format=None)
对于详细视图(在 url 中有主键),请求方法使用以下映射
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()
)。
现在,特别是在您的情况下,您通常会使用看起来像
的 APIView
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
-> list
。我还更新了名称以表明它不仅仅是一个普通视图(因为 ViewSet
不能以相同的方式初始化),但这不是必需的。
所以有了这个新视图,您只需像注册其他视图一样在路由器中注册它。您需要一个 base_name
以便可以生成 url 名称(通常这会从查询集中提取)。
router.register(r'updatetime', views.UpdateTimeViewSet, base_name='updatetime')
现在 updatetime
端点将在 API 根中可用,您只需调用端点(一个简单的 GET 请求)即可获得最新时间。
还有另一种方法:
urlpatterns = [
# ...
url(r'^you_path/', include(router.urls)),
url(r'^you_path/you_sub_path', views.UpdateTimeView.as_view()),
# ...
]
但是像 Swagger 这样的东西不能用那个
我正在使用 Django REST 框架,并一直在尝试创建一个包含 returns 少量信息的视图,并将其注册到我的路由器上。
我有四个存储信息的模型,它们都有一个 created_time
字段。我试图在单个视图中创建 returns 最近对象(基于 created_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 root 时它会出现在我的其他端点上。
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)
这可以吗?以及如何完成?
路由器工作 with a ViewSet
并且不是为普通视图设计的,但这并不意味着您不能在普通视图中使用它们。通常它们与模型一起使用(和 ModelViewSet
),但它们可以在没有它们的情况下使用 GenericViewSet
(如果您通常使用 GenericAPIView
)和 ViewSet
(如果你只想使用 APIView
).
对于列表视图,请求方法映射到 ViewSet
方法,如下所示
GET
->list(self, request, format=None)
POST
- >create(self, request, format=None)
对于详细视图(在 url 中有主键),请求方法使用以下映射
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()
)。
现在,特别是在您的情况下,您通常会使用看起来像
的APIView
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
-> list
。我还更新了名称以表明它不仅仅是一个普通视图(因为 ViewSet
不能以相同的方式初始化),但这不是必需的。
所以有了这个新视图,您只需像注册其他视图一样在路由器中注册它。您需要一个 base_name
以便可以生成 url 名称(通常这会从查询集中提取)。
router.register(r'updatetime', views.UpdateTimeViewSet, base_name='updatetime')
现在 updatetime
端点将在 API 根中可用,您只需调用端点(一个简单的 GET 请求)即可获得最新时间。
还有另一种方法:
urlpatterns = [
# ...
url(r'^you_path/', include(router.urls)),
url(r'^you_path/you_sub_path', views.UpdateTimeView.as_view()),
# ...
]
但是像 Swagger 这样的东西不能用那个