Reputation: 406
I am trying to change all my class-based views to function-based views and I am having difficulty converting the following class:
class PostUpdateView(LoginRequiredMixin, UserPassesTestMixin, SuccessMessageMixin, UpdateView):
model = Post
fields = ['image', 'title', 'category', status', 'description']
template_name = 'blog/post-form.html'
success_message = 'Your post has been updated.'
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_context_data(self, **kwargs):
context = super(PostUpdateView, self).get_context_data(**kwargs)
context['title'] = 'Update post'
context['submit'] = 'Update'
return context
def get_success_url(self):
author = self.object.author
return reverse_lazy( 'profile', kwargs={'author': author.username})
The function and form should do exactly what this class-based view does, so if anyone can help me out, please let me know.
Upvotes: 1
Views: 1166
Reputation: 477853
You can specify a .form_class
attribute [Django-doc] in an UpdateView
(as well as in a CreateView
). So we can create a form like:
# app/forms.py
from django import forms
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ['image', 'title', 'category', 'status', 'description']
widgets = {
'image': …
}
Where you replace …
with the widget you want to use for the image
field.
Then you can plug in that form:
# app/views.py
from app.forms import PostForm
class PostUpdateView(LoginRequiredMixin, UserPassesTestMixin, SuccessMessageMixin, UpdateView):
model = Post
form_class = PostForm
template_name = 'blog/post-form.html'
success_message = 'Your post has been updated.'
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_context_data(self, **kwargs):
context = super(PostUpdateView, self).get_context_data(**kwargs)
context['title'] = 'Update post'
context['submit'] = 'Update'
return context
def get_success_url(self):
author = self.object.author
return reverse_lazy( 'profile', kwargs={'author': author.username})
Behind the curtains, if you do not specify a form_class
, Django will simply make one for you with the modelform_factory
[Django-doc], so by using another ModelForm
, we do not change the logic of using the form.
Upvotes: 2