我正在尝试从Django应用程序的数据库中删除对象。
这个想法是从html文件中获取主要内容并将其发布为表单。我不明白如何传递主键以正确的方式发布删除请求。
我在关于stackoverflow,django doc和其他资源的所有关于基于类的视图DeleteView的内容上都做了研究,而没有弄清楚它是如何工作的。
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/
在代码的主要摘要下面,如果您缺少所需的内容,请告诉我。
views.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 %}
urls.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'),
]
models.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
UPDATE1 :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
答案 0 :(得分:1)
request.POST
是表单输入的相应名称/值的键/值对的QueryDict
。
我认为问题在于您忘记在name
输入中添加pk
,因此当您的视图获取request.POST
对象时,没有名为{{ 1}}。
pk
的键,并且没有给出默认值,则 .getlist('arg')
将返回一个空列表。
这应该可以解决您的问题:
arg
我相信您遇到的错误与您原来的问题无关,并且可能应该作为一个新问题提出。话虽如此,我仍然会尽力提供帮助,我只是没有使用DRF的经验。
根据docs:
.accepted_renderer
将用于呈现响应的呈现器实例。 从视图返回响应之前,由APIView或@api_view自动设置。
也:
除非出于某种原因想要大量自定义REST框架,否则对于返回Response对象的视图,应始终使用APIView类或@api_view函数。这样做可以确保视图可以执行内容协商,并在从视图返回响应之前为其选择适当的渲染器。
我认为您最好的选择是使用<input type="hidden" name="pk" value="{{ pk }}">
装饰器(尽管我不确定这是否适用于基于分类的视图)。
@api_view