Django/Tastypie - DELETE请求删除所有内容

1 投票
1 回答
1277 浏览
提问于 2025-04-18 03:38

我有一个这样的模型

class Open(models.Model):
    name=models.TextField()
    opened=models.DateTimeField(auto_now_add=True)
    user=models.ForeignKey(User)

还有这些资源

class UserResource(ModelResource):
    class Meta:
        queryset = User.objects.all()
        resource_name = 'user'
class OpenResource(ModelResource):
    user = fields.ForeignKey(UserResource,'user')

    class Meta:
        queryset = Open.objects.all()
        resource_name = 'open'

我想从某个用户的开放集合中删除一个开放对象。为了发送请求,我使用了以下代码(用的是Requests库):

content={"name":file_path,
        "user":"/api/v1/user/2/"}
requests.post(
                url='http://localhost:8000/api/v1/open/',
                data=json.dumps(content),
                headers={'content-type':'application/json'},
)

这段代码运行得很好,完全达到了我的目的。

但是,当我尝试用类似的代码来删除时:

content={"name":file_path,
        "user":"/api/v1/user/2/"}
requests.delete(
                url='http://localhost:8000/api/v1/open/',
                data=json.dumps(content),
                headers={'content-type':'application/json'},
)

结果却是把那个用户(在这个例子中,用户ID是2)的所有开放对象都删除了,而不是只删除“名称”为file_path并且“用户”为"/api/vi/user/2/"的开放对象。

我漏掉了什么呢?

1 个回答

3

列表和详情的区别

RESTful 方法分为两种类型:

详情(用于 GET、PUT 和 DELETE):

/api/v1/objects/1/

和列表(用于 GET、PUT 和 DELETE):

/api/v1/objects/

POST 和 PATCH 有点不同。

这意味着 DELETE /api/v1/objects/ 会删除所有对象。

要删除一个特定的对象,你需要提供带有 ID 的路径:

DELETE /api/v1/objects/1/

查看文档链接

Tastypie 中的过滤工作原理:

你不能随便往内容里加东西,然后希望 Tastypie 能识别。所有不该在那里的信息都会被 Tastypie 忽略。

如果你想过滤你的列表,可以使用查询集参数:

/api/v1/objects/?name=asdfasdf&user=2

并允许过滤这些:

from tastypie.constants import ALL, ALL_WITH_RELATIONS
class Open(models.Model):
    name=models.TextField()
    opened=models.DateTimeField(auto_now_add=True)
    user=models.ForeignKey(User)
    filtering = {'name': ALL, 'user': ALL_WITH_RELATIONS}

在这些更改之后,你将能够删除一组对象:

DELETE /api/v1/objects/?name=asdfasdf&user=5

查看文档链接

编辑:

所以你的调用看起来会是这样的:

import urllib
content={"name":file_path,
        "user":"/api/v1/user/2/"} # If doesn't work change '/api/v1/user/2/' into 2 I am not sure about this
url = 'http://localhost:8000/api/v1/open/?' + urllib.urlencode(content)
requests.delete(
                url=url,
                data=None,
                headers={'content-type':'application/json'},
)

撰写回答