Django/Python - функция Delete в UpdateView дублирует, а не удаляет
Я создал приложение на Django, которое позволяет пользователям вводить данные о своих биржевых сделках в качестве инструмента для ведения журнала. Когда пользователь нажимает на отдельную запись в журнале на индексной странице, он попадает на страницу с подробной информацией об этой отдельной записи (single_entry.html). Эта страница обрабатывается с помощью UpdateView. На этой странице пользователь может редактировать/обновлять любую информацию, а также УДАЛЯТЬ конкретную запись. Для этого я импортировал модуль DeletionMixin из django.views.generic.edit.
Однако, когда я нажимаю на кнопку "Удалить" в форме, запись дублируется, а не удаляется! Кто-нибудь знает, почему это происходит? Спасибо за помощь!
Вот мой вид, основанный на классе, в файле views.py:
class SingleEntryView(UpdateView):
template_name = "single_entry.html"
model = Entry
fields = ['ticker', 'strategy', 'result', 'comments', 'image']
success_url = '/'
def post(self, request, *args, **kwargs):
if "delete_button" in self.request.POST:
return self.delete(request, *args, **kwargs)
def update_post(self, form, pk):
if "update_button" in self.request.POST:
form.instance.user = self.request.user
return super(SingleEntryView, self).update_post(form)
single_entry.html:
{% extends 'base.html' %}
{% block title %}
Trading Journal - Entry
{% endblock title %}Trading Journal
{% block content %}
<form method="POST" action="/">
{% csrf_token %}
{% for field in form %}
{{field.label_tag}}
{{field}}
{% if field.errors %}
<small class="error">{{ field.errors|striptags }}</small>
{% endif %}
{% endfor %}
<button type="submit" name="update_button">Save</button>
<button type="submit" name="delete_button">Delete</button>
</form>
<img src="{{ entry.image.url }}" alt="{{ entry.result }}">
{% endblock content %}
urls.py:
from django.urls import path
from django.contrib import admin
from . import views
urlpatterns = [
path("", views.EntryView.as_view()),
path("entries/<int:pk>/", views.SingleEntryView.as_view(), name="single-entry"),
path("admin/", admin.site.urls)
]
Обратившись за помощью к ChatGPT, он порекомендовал следующий код в моем UpdateView (который дал мне ту же проблему):
def post(request, self, form):
print("post request")
print("request.post", request.POST)
if "delete" in request.POST:
print("delete found")
return self.delete_entry()
else:
print("else statement")
#return super(SingleEntryView, self).post(request, form)
return super().post(request, form)
#return super().post(request, *args, **kwargs)
def delete_entry(self):
entry = self.get_object()
print("get object")
entry.delete()
messages.success(self.request, "Your entry was deleted successfully.")
return redirect("/")
В вашем коде, похоже, вы пытаетесь обработать удаление записи в методе post()
вашего класса SingleEntryView
. Но DeleteView
, предоставляемый Django, уже обрабатывает логику удаления, поэтому вам не нужно переопределять метод post()
для удаления. Теперь измените свой код следующим образом :
from django.urls import reverse_lazy
from django.contrib import messages
from django.views.generic import DeleteView
class SingleEntryDeleteView(DeleteView):
model = Entry
template_name = "delete_entry.html"
success_url = reverse_lazy('index')
def delete(self, request, *args, **kwargs):
messages.success(self.request, "Your entry was deleted successfully.")
return super().delete(request, *args, **kwargs)
Теперь он будет обрабатывать процесс удаления, и запись будет удалена без дублирования.
А в вашем single_entry.html
вы можете создать ссылку или кнопку для удаления вида, например, так :
<form method="POST" action="{% url 'single-entry-delete' entry.pk %}">
{% csrf_token %}
<button type="submit">Delete</button>
</form>
Убедитесь, что у вас есть соответствующий шаблон URL в вашем urls.py
для SingleEntryDeleteView
:
from django.urls import path
from .views import SingleEntryDeleteView
urlpatterns = [
path('entries/<int:pk>/delete/', SingleEntryDeleteView.as_view(), name='single-entry-delete'),
]
Теперь все должно работать нормально. Счастливого кодинга!
Здесь есть две проблемы. Первая заключается в том, что вы не прокладываете маршрут обратно к вашему представлению, вы должны сделать POST-запрос по тому же пути, так:
<!-- no action 🖟 -->
<form method="POST">
<!-- … -->
</form>
в представлении вы должны обработать сценарий удаления с помощью self.object.delete()
:
class SingleEntryView(UpdateView):
template_name = 'single_entry.html'
model = Entry
fields = ['ticker', 'strategy', 'result', 'comments', 'image']
success_url = '/'
def post(self, request, *args, **kwargs):
if 'delete_button' in self.request.POST:
self.object.delete()
return HttpResponseRedirect(self.get_success_url())
return super().post(request, *args, **kwargs)
def form_valid(self, form):
form.instance.user = self.request.user
return super().form_valid(form)
Note: Since PEP-3135 [pep], you don't need to call
super(…)
with parameters if the first parameter is the class in which you define the method, and the second is the first parameter (usuallyself
) of the function.