简体   繁体   中英

How can I convert my class-based view to function-based views? - Django

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.

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 

class PostUpdateView(LoginRequiredMixin, UserPassesTestMixin, SuccessMessageMixin, UpdateView):
    model = Post
    
    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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM