【发布时间】:2016-11-19 23:57:24
【问题描述】:
我有一个网站,我在数据库中有一堆记录。有两个字段,Name 和 Comment。 models.py:
class Db_test(models.Model):
name = models.CharField(max_length=50)
comment = models.CharField(max_length=200)
created = models.DateField(auto_now_add=True)
modified = models.DateField(auto_now=True)
class Meta:
db_table = "db_test"
我有一个页面,其中显示了所有记录,旁边有一个删除按钮。我的当前页面:
我有以下views.py(只是相关功能):
def delete(request):
objects = Db_test.objects.all()
items = []
if request.method == "POST":
print(int(list(request.POST)[-1]))
objects[int(list(request.POST)[-1])].delete()
for obj in objects:
items.append([obj.name, obj.comment])
return render(request, "models_test/delete.html", {"values": items})
相关的 DTL 部分:
{% for i in values %}
<form method="POST">
{% csrf_token %}
<p>{{ forloop.counter }}: {{ i.0 }}<input type="submit" name={{forloop.counter0}} value="X"></p>
<p>{{ i.1 }}</p>
</form>
{% endfor %}
除了偶尔会引发错误之外,所有这些都可以正常工作:
Traceback (most recent call last):
File "/home/mooncheesez/Desktop/django_projects/test_project/venv/lib/python3.4/site-packages/django/core/handlers/base.py", line 149, in get_response
response = self.process_exception_by_middleware(e, request)
File "/home/mooncheesez/Desktop/django_projects/test_project/venv/lib/python3.4/site-packages/django/core/handlers/base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/mooncheesez/Desktop/django_projects/test_project/venv/testproject/models_test/views.py", line 32, in delete
print(int(list(request.POST)[-1]))
ValueError: invalid literal for int() with base 10: 'csrfmiddlewaretoken'
这行是罪魁祸首:
objects[int(list(request.POST)[-1])].delete()
出于某种奇怪的原因,request.POST 仅包含 csrf_token,但不包含提交按钮。请注意,它也只是偶尔发生。
我在 stackoverflow 上搜索了一下,只发现了这个用复选框删除的帖子:Django: writing a view to delete an item with checkboxes
我该怎么做才能避免这种情况?我正在做的事情有更好的选择吗?
【问题讨论】:
-
你想在这里做什么:
int(list(request.POST)[-1])?request.POST是键/值对的字典。尝试将其转换为列表是没有意义的。尝试根据它们在数据库中的顺序删除对象也没有任何意义 - 您需要改用它们的数据库 ID。 -
@solarissmoke 我明白了。这解释了偶尔的错误。有更好的方法吗?如果是这样,请将其发布为答案! (我会想象像
[x for x in request.POST if x != 'csrfmiddlewaretoken']这样的索引)