Reputation: 710
For my classes PostCreateView
and PostUpdateView
I have the same get_success_url
. Is there a way of standardising your get_success_url
, I want to avoid writing the code twice?
def get_success_url(self):
return reverse('post-detail', args=[self.object.pk])
I was working through a tutorial. A limitation of the tutorial though was you were only shown how to load posts by using the posts primary key (https://rossdjangoawesomeapp2.herokuapp.com/post/6/). I modified the code in the tutorial so you could access posts using their title (https://rossdjangoawesomeapp2.herokuapp.com/post/another-test-please-let-it-work/). Which has resulted in me having duplicate code.
models.py
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now())
author = models.ForeignKey(User, on_delete=models.CASCADE)
url = models.SlugField(max_length=500, blank=True)
def save(self, *args, **kwargs):
self.url= slugify(self.title)
super().save(*args, **kwargs)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk': self.pk})
views.py
class PostCreateView(LoginRequiredMixin, CreateView):
model = Post
fields = ['title', 'content']
def get_success_url(self):
return reverse('post-detail', args=[self.object.pk])
def form_valid(self, form):
form.instance.author = self.request.user
# will save the form and redirect to the success_url
return super().form_valid(form)
class PostUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model = Post
fields = ['title', 'content']
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
def test_func(self):
post = self.get_object()
if self.request.user == post.author:
return True
return False
def get_success_url(self):
return reverse('post-detail', args=[self.object.pk])
Upvotes: 1
Views: 556
Reputation: 477190
For my classes
PostCreateView
andPostUpdateView
I have the sameget_success_url
. Is there a way of standardising yourget_success_url
, I want to avoid writing the code twice?
Yes, not writing it at all. If you do not specify a get_success_url
, or success_url
, Django will take the get_absolute_url
of the object (so here the Post
object). Hence if you do not specify it, then it will already redirect to the correct url, this is specified in the documentation for the get_success_url
method [Django-doc]:
Determine the URL to redirect to when the form is successfully validated. Returns
django.views.generic.edit.ModelFormMixin.success_url
if it is provided; otherwise, attempts to use theget_absolute_url()
of the object.
So we can remove the get_success_url
methods:
class PostCreateView(LoginRequiredMixin, CreateView):
model = Post
fields = ['title', 'content']
# no get_success_url
def form_valid(self, form):
form.instance.author = self.request.user
class PostUpdateView(LoginRequiredMixin, UpdateView):
model = Post
fields = ['title', 'content']
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
def get_queryset(self, *args, **kwargs):
return super().get_queryset(*args, **kwargs).filter(
author=self.request.user
)
# no get_success_url
Upvotes: 1