为每个记录创建一个删除按钮 [英] Creating a delete button for each record

查看:42
本文介绍了为每个记录创建一个删除按钮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个网站,我在数据库中有一堆记录.有两个字段, Name Comment . models.py :

I have a website which I have a bunch of records in the database. There are two fields, Name and 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"

我有一个页面,其中显示所有记录,并在其旁边有一个删除按钮.我当前的页面:

I have a page where all the records are displayed with a delete button next to it. My current page:

我有以下 views.py (只是相关的功能):

I have the following views.py (just the relevant function):

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 %}

所有这些工作正常,除了偶尔会引发错误:

All this works fine except that it occasionally raises an error:

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 ,但不包含提交的按钮.请注意,它也只会偶尔发生.

For some odd reason, request.POST only contains the csrf_token but not the submitted button. Note that it only happens occasionally too.

我在stackoverflow周围进行了搜索,只找到了此复选框需要删除的帖子:

I searched around stackoverflow and I only found this post for deleting with checkboxes: Django: writing a view to delete an item with checkboxes

如何避免这种情况?我在做什么,还有更好的选择吗?

What do I do to avoid this? Are there better alternatives for what I am doing?

推荐答案

我建议完全采用另一种方法.

I would suggest a different approach altogether.

在您看来,传递对象本身:

In your view, pass the object itself:

objects = Db_test.objects.all()
return render(request, "models_test/delete.html", {"values": objects})

在您的模板中:

{% for obj in object %}
    <form method="POST">
        {% csrf_token %}
        <p>{{ forloop.counter }}: {{ obj.name }}<input type="submit" name="delete_items" value="{{ obj.pk }}"></p>
        <p>{{ obj.comment }}</p>
    </form>
{% endfor %}

再次在您看来:

if request.method == "POST":
    # Fetch list of items to delete, by ID
    items_to_delete = request.POST.getlist('delete_items')
    # Delete those items all in one go
    Db_test.objects.filter(pk__in=items_to_delete).delete()

一些一般性评论:

  • 将诸如 [obj.name,obj.comment] 之类的列表传递到模板没有任何好处.只需传递对象本身即可.这样会更容易维护.

  • There is nothing to be gained by passing a list like [obj.name, obj.comment] to your template. Just pass the object itself. This will be much easier to maintain.

在这里基于自然数据库顺序进行更改绝对不是正确的方法-实际上这是危险且容易出错的(例如,如果您在渲染表单时将项目添加到数据库中该怎么办?).您的数据库对象有一个唯一的ID来标识它们-使用该ID.

Making changes based on natural database order is definitely not the right approach here - in fact it is dangerous and error-prone (e.g, what if items were added to the database while you were rendering the form?). Your database objects have a unique ID to identify them - use that.

request.POST 是一本字典.将其转换为列表没有任何意义.如果您提供所有具有相同名称的输入列表,则可以使用 getlist() 来获取它们.

request.POST is a dictionary. Converting it to a list doesn't make sense. If you supply a list of inputs all with the same name, you can use getlist() to fetch them.

这篇关于为每个记录创建一个删除按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆