Основанный класс представления - вызывается метод success_url, но перенаправление, похоже, не работает
Я использую класс основанного представления для обновления статьи в моем приложении под названием article. Я реализую его так же, как работает UpdateView, однако я не могу заставить его перенаправлять после проверки формы. Я вызвал метод success_url для перенаправления в детальное представление, но это не работает. Я что-то упустил?
Я установил get_absolute_url в моделях,
#models.py
class Article(models.Model):
def get_absolute_url(self):
return reverse('articles:article-detail', kwargs={"id": self.id})
и в урлах
#urls.py
app_name = 'articles'
urlpatterns = [
path('<int:id>/edit/', ArticleUpdateView.as_view(), name='article-edit'),
path('<int:id>/', ArticleDetailView.as_view(), name='article-detail'),
]
и по взглядам:
#views.py
class ArticleUpdateView(View):
template_name = 'articles/article_edit.html'
def get_success_url(self):
id = self.kwargs.get('id')
return reverse('articles:article-detail', kwargs={'id': id})
def get_object(self):
id = self.kwargs.get('id')
obj = None
if id is not None:
obj = get_object_or_404(Article, id=id)
return obj
def get(self, request, id=None, *args, **kwargs):
context = {}
obj = self.get_object()
if obj is not None:
form = ArticleModelForm(instance=obj)
context['article'] = obj
context['form'] = form
return render(request, self.template_name, context)
def post(self, request, id=None, *args, **kwargs):
context = {}
obj = self.get_object()
if obj is not None:
form = ArticleModelForm(request.POST, instance=obj)
if form.is_valid():
form.save()
context['article'] = obj
context['form'] = form
return render(request, self.template_name, context)
Я пробовал использовать его на классе UpdateView и перенаправление, кажется, работает нормально, я хотел бы использовать его на классе основанного представления.
Базовый класс django View не будет автоматически вызывать что-то вроде get_success_url()
, это то, что добавляется в функциональность общего представления на основе класса, например UpdateView
из другого класса, который он наследует. Если вы хотите перенаправить в базовом представлении, то вам нужно будет фактически вставить вызов перенаправления.
В вашем файле views.py вы можете импортировать from django.http import HttpResponseRedirect
и затем в утверждении if form.isvalid():
в вашем представлении вы можете добавить строку return HttpResponseRedirect(self.get_success_url())
. Вызов функции get_success_url()
сам по себе ничего не делает с тем, как вы ее определили, потому что ярлык reverse()
просто генерирует url на основе имени и аргументов, которые вы передаете в функцию.
Часто, сначала нужно импортировать reverse_lazy
class ArticleUpdateView(UpdateView):
.....
def get_success_url(self):
return reverse_lazy('article-detail', kwargs={'pk': self.object.pk})
Если вы используете форму, вы можете выполнить перенаправление, задав метод pull или get для формы и установив значение action на url, который вы хотите перенаправить непосредственно в вашем шаблоне в html. Вот пример :
<form id="contactForm" name="updateArticle" action="{% url 'article-detail' %}" method="post">
{% csrf_token %}
{% for field in form %}
/* Your code */
{% endfor %}
<button type="submit">Update Post</button>
</form>
Затем в вашем ArticleDetailView вы можете установить ваш метод post() для отображения страницы подробностей:
class ArticleDetailsView(View):
template_name = 'articles/article_details.html'
post(self, request, *args, **kwargs):
# Your code
return render(request, self.template_name, context)
Вы также можете использовать метод redirect() вместо render(). Вы можете найти документацию здесь.
from django.views.generic.edit import FormMixin
class ArticleUpdateView(View, FormMixin):
...
FormMixin
содержит магию, которую вы ищете.