Home > Enterprise >  Based View Class - called success_url method but redirect doesn't seem to work
Based View Class - called success_url method but redirect doesn't seem to work

Time:11-25

I am using a based view class to update an article in my app named article. I am implementing it just like how UpdateView works however i can't seem to make it redirect it after validating the form. I called success_url method to redirect into the detail view, but it doesn't work. Am I missing something?

I set get_absolute_url in models,

#models.py

class Article(models.Model):
def get_absolute_url(self):
        return reverse('articles:article-detail', kwargs={"id":  self.id})

and in urls

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

and on views:

#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)

I tried using it on UpdateView class and redirect seems to work fine, i'd like to use it on based view class.

CodePudding user response:

The django base View class will not call something like get_success_url() automatically, that is something that is added in to the functionality of a generic class based view like UpdateView from another class that it inherits. If you want to redirect in a base View then you will need to actually put in a redirect call.

In your views.py file you can import from django.http import HttpResponseRedirect and then in your if form.isvalid(): statement in your view you can add in the line return HttpResponseRedirect(self.get_success_url()). Just calling get_success_url() does nothing on its own with how you have defined it because the reverse() shortcut just generates the url based on the name and arguments that you pass into the function.

CodePudding user response:

Chack this, first you need to import reverse_lazy

class ArticleUpdateView(UpdateView):
.....

    def get_success_url(self):
         return reverse_lazy('article-detail', kwargs={'pk': self.object.pk})

CodePudding user response:

If you are using a form you can proceed the redirection by setting a pull or get method for the form and set the action value to the url you want to redirect directly in your template in html. Here's an exemple :

<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>

Then in your ArticleDetailView you can set your post() method to render the details page:

class ArticleDetailsView(View):
    template_name = 'articles/article_details.html'

    post(self, request, *args, **kwargs):
        # Your code
        return render(request, self.template_name, context)

You can also use the redirect() method instead of the render(). You can find the documentation here.

CodePudding user response:

from django.views.generic.edit import FormMixin

class ArticleUpdateView(View, FormMixin):
    ...

FormMixin contains the magic you seek.

  • Related