Почему я получаю ошибку No Reverse Match при отправке с помощью UpdateView?
В настоящее время я использую UpdateView для добавления функции редактирования в мой проект Django. Он работает правильно, поскольку я могу редактировать свои данные, однако, когда я отправляю новые данные, он возвращает ошибку NoReverseMatch:
NoReverseMatch at /MyHealth/edit/8 Обратное соответствие для 'health_hub_history' не найдено. 'health_hub_history' не является допустимой функцией представления или именем шаблона.
Я исследовал это и добавил get_absolute_url в свою модель, но он не работает. Любая помощь будет оценена по достоинству!
models.py:
from django.db import models
from django.contrib.auth.models import User
from django.urls import reverse
class HealthStats(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
date = models.DateField(auto_now=True)
weight = models.DecimalField(max_digits=5, decimal_places=2)
run_distance = models.IntegerField(default=5)
run_time = models.TimeField()
class Meta:
db_table = 'health_stats'
ordering = ['-date']
def get_absolute_url(self):
return reverse('health_hub_history')
def __str__(self):
return f"{self.user} | {self.date}"
urls.py:
from django.urls import path
from django.contrib.staticfiles.storage import staticfiles_storage
from django.views.generic.base import RedirectView
from . import views
app_name = 'HealthHub'
urlpatterns = [
path('', views.home, name='home'),
path('MyHealth/', views.health_hub, name='health_hub'),
path('MyHealth/update', views.UpdateHealth.as_view(), name='health_hub_update'),
path('MyHealth/history', views.health_history, name='health_hub_history'),
path('favicon.ico', RedirectView.as_view(url=staticfiles_storage.url("favicon.ico"))),
path('MyHealth/delete/<item_id>', views.delete_entry, name='health_hub_delete'),
path('MyHealth/edit/<int:pk>', views.EditHealth.as_view(), name='health_hub_edit'),
]
Views.py:
class EditHealth(UpdateView):
model = HealthStats
template_name = 'health_hub_edit.html'
fields = ['weight', 'run_distance', 'run_time']
health_hub_edit.html:
{% extends 'base.html' %}
{% load static %}
{%load crispy_forms_tags %}
{% block content %}
<div class="container-fluid">
<div class="row">
<div class="col-sm-12 text-center">
<h1>Edit my Data</h1>
</div>
</div>
</div>
<div class="container-fluid">
<div class="row justify-content-center">
<div class="col-auto text-center p-3">
<form method="post" style="margin-top: 1.3em;">
{{ form | crispy }}
{% csrf_token %}
<button type="submit" class="btn btn-signup btn-lg">Submit</button>
</form>
</div>
</div>
<div class="row justify-content-center">
</div>
</div>
{% endblock content %}
Вы можете сделать следующее:
class EditHealth(UpdateView):
model = HealthStats
template_name = 'health_hub_edit.html'
fields = ['weight', 'run_distance', 'run_time']
def get(self, request):
return HttpResponse("health_hub")
def post(self, request):
# do something
return redirect("health_hub")
urlpatterns = patterns('',
url('', views.home, name='home'),
url('MyHealth/', views.health_hub, name='health_hub'),
url('^MyHealth/update', views.UpdateHealth.as_view(), name='health_hub_update'),
url('MyHealth/history', views.health_history, name='health_hub_history'),
url('favicon.ico', RedirectView.as_view(url=staticfiles_storage.url("favicon.ico"))),
url('MyHealth/delete/<item_id>', views.delete_entry, name='health_hub_delete'),
url('MyHealth/edit/<int:pk>', views.EditHealth.as_view(), name='health_hub_edit'),
)
Это решит вашу проблему
Эта ошибка возникает потому, что django не смог разрешить url вы не указали первичный ключ, на котором основывается запрос. вам следует модифицировать эту функцию
def get_absolute_url(self):
return reverse('health_hub_history', kwargs={'user': self.user})
также, что health_history url является представлением на основе класса, вы должны добавить .as_view() в конец и соблюдать camel casing
Последнее - ваш url должен соблюдать указанный первичный ключ
Я нашел ответ на этот вопрос здесь:
https://stackoverflow.com/a/48068932/19053957
Похоже, все, что мне нужно было сделать, это указать имя приложения перед именем URL в get_absolute_url()!