这是视图集
class MobileDeviceViewset(ModelViewSet):
@action(
methods=['post', 'put', 'patch'],
url_path='token',
detail=True,
)
def update_token(self, request, *args, **kwargs) -> Response:
...
@action(
methods=['get'],
url_path='token',
detail=True,
)
def get_token(self, request, *args, **kwargs) -> Response:
...
所以我想在这里做一个端点/token/
,应用程序将发送一个GET请求来检查是否有令牌,如果有则获取令牌。我还想使用相同的/token/
端点向其发送更新的令牌。当前发生的是,我收到一条错误消息,告诉我该端点上不允许使用POST / PATCH / PUT方法,因此它似乎只能识别get_token
方法。这里的令牌对象实际上是一个名为MobileDeviceUser
的ManyToMany贯穿模型,因此我不只是尝试更新MobileDevice
对象上的字段。
答案 0 :(得分:1)
由于两种情况下您的url_path
和detail
相同,所以为什么要在视图中使用两种独立的方法?
无论如何,我会推荐这种方式,
class MobileDeviceViewset(ModelViewSet):
# your code
@action(methods=['get', 'post', 'put', 'patch'], url_path='token', detail=True, )
def my_action(self, request, *args, **kwargs):
if request.method == 'GET':
return self.get_token(request, *args, **kwargs)
else:
return self.update_token(request, *args, **kwargs)
def update_token(self, request, *args, **kwargs):
return Response("update token response--{}".format(request.method))
def get_token(self, request, *args, **kwargs):
return Response("update token response--{}".format(request.method))
然后,您必须在URL配置中进行一些更改,
from django.urls import path
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register('mysample', MobileDeviceViewset, base_name='mobile-device')
actions = {
"get": "my_action",
"post": "my_action",
"put": "my_action",
"patch": "my_action"
}
urlpatterns = [
path('mysample/<pk>/token/', MobileDeviceViewset.as_view(actions=actions))
] + router.urls
因此,您的URL将类似于 ..../mysample/3/token/
注意
此解决方案在Python 3.6
,Django==2.1
和DRF==3.8.2
下进行了测试
Method Not Allowed
错误?当请求到达Django时,它会在URL配置中搜索模式,如果发生匹配,则将请求发送到相应的视图。
在您的情况下,您已经定义了两个具有相同URL(如下所示)的视图(是的,虽然它是动作)。
actions = {
"post": "update_token",
"put": "update_token",
"patch": "update_token"
}
urlpatterns = [
path('mysample/<pk>/token/', MobileDeviceViewset.as_view(actions={"get": "get_token"})),
path('mysample/<pk>/token/', MobileDeviceViewset.as_view(actions=actions))
] + router.urls
在这种情况下,将发出一个请求(将其作为 HTTP POST ),并且URL调度程序将重定向到满足URL路径的第一个视图。因此,POST请求进入了 get_token
方法,但是,仅允许 GET 方法
方法1:
如我在顶部所述,请使用常见操作并区分 HTTP方法并调用适当的方法
方法2:
为这两个操作使用不同的URL路径,例如
actions = {
"post": "my_action",
"put": "my_action",
"patch": "my_action"
}
urlpatterns = [
path('mysample/<pk>/get-token/', MobileDeviceViewset.as_view(actions={"get": "get_token"})),
path('mysample/<pk>/update-token/', MobileDeviceViewset.as_view(actions=actions))
] + router.urls
答案 1 :(得分:0)
您可以通过:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Spawn : MonoBehaviour {
public Spawn04[] pest;
public GameObject plantPest;
void Start () {
}
[System.Obsolete]
void Update () {
if(plantPest.active)
{
SpawnObjects();
}
}
void SpawnObjects()
{
int i = Random.Range(0, 100);
for(int j = 0; j < pest.Length; j++)
{
if(i >= pest[j].minProbabilityRange && i <= pest[j].maxProbabilityRange)
{
Instantiate(pest[j].spawnObject, transform.position, transform.rotation);
break;
}
if(pest[j].pestCount >= pest[j].maxNumber)
{
Destroy(this.gameObject);
}
}
}
}
[System.Serializable]
public class Spawn04
{
public GameObject spawnObject;
public int minProbabilityRange = 0;
public int maxProbabilityRange = 0;
public int maxNumber = 1;
public int pestCount = 0;
}