gpt4 book ai didi

python - Django索引错误: pop from empty list within DeleteView

转载 作者:行者123 更新时间:2023-12-01 07:12:13 24 4
gpt4 key购买 nike

我正在尝试从 Django 应用程序的数据库中删除一个对象。

这个想法是从 html 文件中获取主要内容并将其发布到表单中。我不明白应该如何传递主键以正确的方式发布我的删除请求。

我查阅了在 stackoverflow、django doc 和其他来源上找到的有关基于类的 View DeleteView 的所有内容,但没有弄清楚它是如何工作的。

例如: Django delete FileField

How to delete a record in Django models?

Python Django delete current object

How to delete a record in Django models?

https://docs.djangoproject.com/en/2.2/topics/db/queries/

https://docs.djangoproject.com/en/2.2/ref/class-based-views/generic-editing/#django.views.generic.edit.DeleteView

在代码的主要片段下方,如果您缺少所需的内容,请告诉我。

View .py

class SelectFileDelView(TemplateView):
"""
This view is used to select a file from the list of files in the server.
After the selection, it will send the file to the server.
The server will then delete the file.
"""
template_name = 'select_file_deletion.html'
parser_classes = FormParser
queryset = FileModel.objects.all()

def get_context_data(self, **kwargs):
"""
This function is used to render the list of files in the MEDIA_ROOT in the html template
and to get the pk (primary key) of each file.
"""
context = super().get_context_data(**kwargs)
media_path = settings.MEDIA_ROOT
myfiles = [f for f in listdir(media_path) if isfile(join(media_path, f))]
pk_list = []
for value in myfiles:
pk = FileModel.objects.filter(file=value).values_list('pk', flat=True)
pk_list.append(pk)
file_and_pk = zip(myfiles, pk_list)
context['filename'] = file_and_pk
return context


class FileDeleteView(DeleteView):
"""
This class contains the method to delete a file interacting directly with the API.
DELETE requests are accepted.
"""
model = FileModel
fields = ['file']
template_name = 'delete_success.html'
success_url = '/delete_success/'

def post(self, request):
"""
This method is used to making predictions on audio files
loaded with FileView.post
"""
pk = request.POST.getlist('pk').pop()
try:
return Response(pk, status=status.HTTP_200_OK)
except ValueError as err:
return Response(str(err), status=status.HTTP_400_BAD_REQUEST)

select_file_deletion.html

{% extends "index.html" %}

{% block content %}
<form action="/App/delete/" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<h5>Please select one file at a time from the list below to delete it from the server.</h5>
{% for myfile, pk in filename %}
<p>Are you sure you want to delete "{{ myfile }}"?</p>
<input type="submit" value="Confirm">
<input type="hidden" name="pk" value="{{ pk }}">
<br>
{% endfor %}
<br>
</form>
{% endblock %}

url.py

urlpatterns = [

# Url to select a file to be deleted and confirm the upload
url('filedelete/', SelectFileDelView.as_view(), name='file_delete'),
url('delete_success/(?P<pk>\d+)/$', FileDeleteView.as_view(), name='delete_success'),

]

模型.py

"""
Models.py includes the database structure of the application.
"""

from django.db import models
from django.conf import settings
from django.dispatch import receiver
from django.db.models.signals import post_delete


class FileModel(models.Model):
file = models.FileField(null=True, blank=True)
timestamp = models.DateTimeField(auto_now_add=True)
path = models.FilePathField(path=settings.MEDIA_ROOT, default=settings.MEDIA_ROOT)


@receiver(post_delete, sender=FileModel)
def submission_delete(sender, instance, **kwargs):
"""
This function is used to delete attachments when a file object is deleted.
Django does not do this automatically.
"""
instance.file.delete(False)

错误:

IndexError at /App/delete/
pop from empty list
Request Method: POST
Request URL: http://127.0.0.1:8000/App/delete/
Django Version: 2.2.4
Exception Type: IndexError
Exception Value:
pop from empty list
Exception Location: /Users/marcogdepinto/PycharmProjects/DjangoRestDeepLearning/App/views.py in post, line 131
Python Executable: /Users/marcogdepinto/anaconda3/bin/python
Python Version: 3.6.9

更新1:html已更改如下

<input type="hidden" name="pk" value="{{ pk }}">

这样做,我得到了

AssertionError at /App/delete/
.accepted_renderer not set on Response

完整回溯如下:

Environment:

Request Method: POST
Request URL: http://127.0.0.1:8000/App/delete/

Django Version: 2.2.4
Python Version: 3.6.9
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'App',
'debug_toolbar']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'debug_toolbar.middleware.DebugToolbarMiddleware']



Traceback:

File "/Users/marcogdepinto/anaconda3/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
34. response = get_response(request)

File "/Users/marcogdepinto/anaconda3/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
145. response = self.process_exception_by_middleware(e, request)

File "/Users/marcogdepinto/anaconda3/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
143. response = response.render()

File "/Users/marcogdepinto/anaconda3/lib/python3.6/site-packages/django/template/response.py" in render
106. self.content = self.rendered_content

File "/Users/marcogdepinto/anaconda3/lib/python3.6/site-packages/rest_framework/response.py" in rendered_content
55. assert renderer, ".accepted_renderer not set on Response"

Exception Type: AssertionError at /App/delete/
Exception Value: .accepted_renderer not set on Response

最佳答案

request.POST 是表单输入相应名称/值的键/值对的 QueryDict

我认为问题在于您忘记在 pk 输入中添加 name,因此当您的 View 获取 request.POST对象,没有名为 pk 的键。

如果没有找到名为 arg 的键,并且没有给出默认值,

.getlist('arg') 将返回一个空列表,这会导致错误得到。

这应该可以解决您的问题:

<input type="hidden" name="pk" value="{{ pk }}">

更新

我相信您遇到的错误与您原来的问题无关,可能应该作为一个新问题提出。话虽这么说,我仍然会尽力提供帮助,我只是没有使用 DRF 的经验。

根据docs :

.accepted_renderer

The renderer instance that will be used to render the response. Set automatically by the APIView or @api_view immediately before the response is returned from the view.

另外:

Unless you want to heavily customize REST framework for some reason, you should always use an APIView class or @api_view function for views that return Response objects. Doing so ensures that the view can perform content negotiation and select the appropriate renderer for the response, before it is returned from the view.

我认为最好的选择是使用 @api_view 装饰器(尽管我不确定这是否适用于基于分类的 View )。

from rest_framework.decorators import api_view
from rest_framework.response import Response

class FileDeleteView(DeleteView):

model = FileModel
fields = ['file']
template_name = 'delete_success.html'
success_url = '/delete_success/'

@api_view
def post(self, request):
...

关于python - Django索引错误: pop from empty list within DeleteView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58149360/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com