Django UpdateView не обновляется
Я создал приложение на Django, которое позволяет пользователям вводить данные о своих биржевых сделках в качестве инструмента для ведения журнала. Когда пользователь нажимает на отдельную запись в журнале на индексной странице, он попадает на страницу с подробной информацией, показывающей всю информацию об этой отдельной записи (single_entry.html). Эта страница обрабатывается с помощью UpdateView. На этой странице пользователь может отредактировать/обновить любую информацию, а также УДАЛИТЬ конкретную запись. На форме есть две кнопки, одна для 'Delete', другая для 'Update'.
Удаление работает нормально. Обновление раньше работало, а теперь почему-то нет! В Entry ничего не обновляется. Также я не могу понять, почему промежуточное ПО 'messages' не выводится на экран. То же самое со всеми моими операторами print(), ничего не выводится на консоль.
Спасибо за помощь!
Вот мой views.py:
from django.forms.models import BaseModelForm
from django.shortcuts import render, redirect
from django.http import HttpResponse, HttpResponseRedirect
from django.views import View
from django.contrib import messages
from django.urls import reverse_lazy
from .forms import EntryForm
from .models import Entry
from django.views.generic.edit import UpdateView, DeletionMixin
from django.views.generic import DeleteView
# Create your views here.
class EntryView(View):
def get(self, request):
entries = Entry.objects.all().order_by("entered_date")
form = EntryForm()
return render(request, "entries.html", {"form":form, "entries":entries})
def post(self, request):
form = EntryForm(request.POST, request.FILES) #must add request.FILES for uploads
print(request.FILES)
if form.is_valid():
form.save()
messages.success(request, "Entry created!")
return redirect("/")
else:
messages.error(request, "Please correct the errors below.")
return render(request, "entries.html", {"form":form})
class SingleEntryView(UpdateView):
template_name = "single_entry.html"
model = Entry
fields = ['ticker', 'strategy', 'result', 'comments', 'image']
success_url = '/'
form = EntryForm
def post(self, request, *args, **kwargs):
if 'delete_button' in self.request.POST:
self.object = self.get_object()
self.object.delete()
messages.success(request, "Entry has been deleted")
return HttpResponseRedirect(self.get_success_url())
return redirect('/')
def form_valid(self, form):
form.instance.user = self.request.user
return super().form_valid(form)
Вот urls.py:
from django.urls import path
from django.contrib import admin
from . import views
urlpatterns = [
path("", views.EntryView.as_view(), name="index"),
path("entries/<int:pk>/", views.SingleEntryView.as_view(), name="single-entry"),
path("admin/", admin.site.urls)
]
Вот single_entry.html:
{% extends 'base.html' %}
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% 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 tyupe="submit" name="delete_button">Delete</button>
</form>
<!-- {% if entry.image.url != Null %} -->
<img src="{{ entry.image.url }}" alt="{{ entry.result }}">
<!-- {% else %} -->
<img src="", alt="{{ entry.result }}">
<!-- {% endif %} -->
{% endblock content %}
Models.py:
from django.db import models
from django.core.validators import MinValueValidator, MaxValueValidator
from django.urls import reverse
from django.utils.text import slugify
class Entry(models.Model):
ONEORB="1-Min ORB"
FIVEORB="5-Min ORB"
ABCD="ABCD"
REVERSAL="Reversal"
PROFIT="Profit"
LOSS="Loss"
RESULT_CHOICES = (
(PROFIT, "Profit"),
(LOSS, "Loss")
)
STRATEGY_CHOICES = (
(ONEORB,"1-Min ORB"),
(FIVEORB,"5-Min ORB"),
(ABCD,"ABCD"),
(REVERSAL,"Reversal")
)
entered_date=models.DateField(auto_now_add=True)
ticker=models.CharField(max_length=8, default="")
strategy=models.CharField(max_length=12, choices=STRATEGY_CHOICES, default="ONEORB")
result=models.CharField(max_length=6, choices=RESULT_CHOICES, default="PROFIT")
comments=models.TextField(max_length=300, blank=True)
image = models.ImageField(upload_to="", null=True, blank=True) #will save to default BASE_DIR which is 'uploads'
def __str__(self):
return f"{self.result} {self.entered_date}"
Forms.py:
from django import forms
from .models import Entry
class EntryForm(forms.ModelForm):
class Meta:
model=Entry
fields='__all__'
Я ожидал, что UpdateView обновит информацию о входе новой информацией.
Вы используете UpdateView
, а на самом деле выполняете self.object.delete()
. Необычно, не правда ли?
Обновление должно обрабатываться в UpdateView
, а удаление - в DeleteView
. Тогда используйте HTML5 <button formaction />
.
views.py
from django.views.generic.edit import UpdateView, DeleteView
from django.contrib.messages.views import SuccessMessageMixin
from django.urls import reverse_lazy
# •••Rest of your views•••
class SingleEntryView(UpdateView, SuccessMessageMixin):
template_name = "single_entry.html"
form = EntryForm
fields = ['ticker', 'strategy', 'result', 'comments', 'image']
model = Entry
success_url = reverse_lazy("index")
success_message = "Entry has been updated"
class DeleteEntry(DeleteView, SuccessMessageMixin):
model = Entry
success_url = reverse_lazy("index")
success_message = "Entry has been deleted"
urls.py
urlpatterns = [
# •••Rest of your paths•••
path("entry/delete/<int:pk>/", views.DeleteEntry.as_view(), name="delete-entry")
# •••Rest of your paths•••
]
single_entry.html
<form method="POST" action="{% url 'single-entry' entry.pk %}">
<!--•••Rest of your form•••-->
<button type="submit" formaction="{% url 'delete-entry' entry.pk %}">Delete</button>
</form>