Search code examples
pythondjango

Is it possible to change the url in view (Django) after a certain operation?


Let's say there is a page of a separate blog article with this url (aviary-ensemble is the slug of the article):

http://127.0.0.1:8002/articles/article/aviary-ensemble/

Now I'm making a comment system and the form for writing a comment is on the same page.

enter image description here

The view for creating a new comment I have formalized as follows: if there is no submitted data, then load the page, if there is - then based on this data create a comment and load the page.

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)

I set the url itself as follows:

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'),
]

The nuance is that after submitting the form the url changes to

http://127.0.0.1:8002/articles/article/aviary-ensemble/admin/

(admin is the username of the active User who is the author of the comment).

Actually, what I want to achieve: after submitting the form, I would like the url to change to http://127.0.0.1:8002/articles/article/aviary-ensemble/.

i.e. without the name addition.

The method of googling gave the following variant (but it did not work - url doesn't change): request.path_info = '/articles/article/' + str(article.slug) + '/'

I double-checked - both url's refer to the same view.

Could you please tell me if it is possible to formalize this somehow?


Solution

  • You should redirect to details page again once comment it saved. your url will be updated to http://127.0.0.1:8002/articles/article/aviary-ensemble/

    This will make code much simpler and align with Django DRY principle.

    import reverse_lazy to use this code

    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)