Можно ли изменить url в представлении (Django) после выполнения определенной операции?
Допустим, есть страница отдельной статьи в блоге с таким url (aviary-ensemble - slug статьи):
http://127.0.0.1:8002/articles/article/aviary-ensemble/
Теперь я делаю систему комментариев, и форма для написания комментария находится на той же странице.
Вид создания нового комментария я формализовал следующим образом: если нет представленных данных, то загружаем страницу, если есть - то на основе этих данных создаем комментарий и загружаем страницу.
def details(request, slug, author=None):
article = models.Article.objects.get(slug=slug)
print(author)
if request.method == 'POST':
if author is not None:
user = User.objects.get(username=author)
print(user.username, type(user))
comment_author = UserProfile.objects.get(user=user)
comment = request.POST['comment_area']
if comment[0] == '@':
receiver = comment[1:].split(', ')[0]
comment_text = comment[1:].split(', ')[1]
models.Comment.objects.create(article=article, author=comment_author, receiver=receiver,
text=comment_text)
else:
models.Comment.objects.create(article=article, author=comment_author, text=comment)
article_comments = models.Comment.objects.filter(article=article)
context = {
'article': article,
'article_comments': article_comments
}
return render(request, 'articles/article.html', context=context)
else:
article.views = article.views + 1
article_comments = models.Comment.objects.filter(article=article)
context = {
'article': article,
'article_comments': article_comments
}
return render(request, 'articles/article.html', context=context)
Я задаю сам url следующим образом:
urlpatterns = [
path('', views.index, name='articles_catalog'),
path('article/<slug:slug>/<str:author>/', views.details, name='comment_creation'),
path('article/<slug:slug>/', views.details, name='details'),
]
Нюанс в том, что после отправки формы url меняется на
http://127.0.0.1:8002/articles/article/aviary-ensemble/admin/
(admin - имя пользователя активного пользователя, который является автором комментария).
Собственно, чего я хочу добиться: после отправки формы я хочу, чтобы url изменился на http://127.0.0.1:8002/articles/article/aviary-ensemble/.
т.е. без добавления имени.
Метод гугления дал следующий вариант (но он не сработал - url не меняется): request.path_info = '/articles/article/' + str(article.slug) + '/'
Я перепроверил - оба url ссылаются на один и тот же вид.
Подскажите, пожалуйста, можно ли это как-то формализовать?
После сохранения комментария вы должны снова перейти на страницу подробностей. Ваш url будет обновлен до http://127.0.0.1:8002/articles/article/aviary-ensemble/
Это значительно упростит код и согласуется с принципом Django DRY.
импортируйте reverse_lazy, чтобы использовать этот код
from django.urls import reverse_lazy
def details(request, slug, author=None):
article = models.Article.objects.get(slug=slug)
print(author)
if request.method == 'POST':
if author is not None:
user = User.objects.get(username=author)
print(user.username, type(user))
comment_author = UserProfile.objects.get(user=user)
comment = request.POST['comment_area']
if comment[0] == '@':
receiver = comment[1:].split(', ')[0]
comment_text = comment[1:].split(', ')[1]
models.Comment.objects.create(article=article, author=comment_author, receiver=receiver,
text=comment_text)
else:
models.Comment.objects.create(article=article, author=comment_author, text=comment)
# redirect the page to details again. you can use reverse_lazy for retriving url
redirect_url = reverse_lazy('details', kwargs={'slug': slug})
return redirect(redirect_url)
else:
article.views = article.views + 1
article_comments = models.Comment.objects.filter(article=article)
context = {
'article': article,
'article_comments': article_comments
}
return render(request, 'articles/article.html', context=context)