Home > other >  The view post.views.view didn't return an HttpResponse object. It returned None instead
The view post.views.view didn't return an HttpResponse object. It returned None instead

Time:11-27

I want to create a new post using PostCreateView and go to the details page of the new post in the next step, but I get this error:

(The view post.views.view didn't return an HttpResponse object. It returned None instead.)

views

class PostDetailView(View):
    """see detail post"""

    def get(self, request, post_id, post_slug):
        post = Post.objects.get(pk=post_id, slug=post_slug)
        return render(request, "post/detail.html", {"post": post})


class PostCreateView(LoginRequiredMixin, View):
    form_class = PostCreateUpdateForm

    def get(self, request, *args, **kwargs):
        form = self.form_class
        return render(request, "post/create.html", {"form": form})

    def post(self, request, *args, **kwargs):
        form = self.form_class(request.POST)
        if form.is_valid():
            new_post = form.save(commit=False)
            new_post.slug = slugify(form.cleaned_data["body"][:20])
            new_post.user = request.user
            new_post.save()
            messages.success(request, "you created a new post", "success")
            return redirect("post:post-detail", new_post.id, new_post.slug)

models

class Post(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    body = models.TextField()
    slug = models.SlugField()
    img = models.ImageField(upload_to="%Y/%m/%d/")
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

urls

app_name = 'post'

urlpatterns = [
    path('', views.BlogView.as_view(), name="home"),
    path('detail/<int:post_id>/<slug:post_slug>/', views.PostDetailView.as_view(), name="post-detail"),
    path('delete/<int:post_id>/', views.PostDeleteView.as_view(), name="post-delete"),
    path('update/<int:post_id>/', views.PostUpdateView.as_view(), name="post-update"),
    path('create/', views.PostCreateView.as_view(), name="post-create"),
]

CodePudding user response:

In case the form is not valid, you should rerender the template with the form, so:

class PostCreateView(LoginRequiredMixin, View):
    form_class = PostCreateUpdateForm

    def get(self, request, *args, **kwargs):
        form = self.form_class
        return render(request, "post/create.html", {"form": form})

    def post(self, request, *args, **kwargs):
        form = self.form_class(request.POST)
        if form.is_valid():
            new_post = form.save(commit=False)
            new_post.slug = slugify(form.cleaned_data['body'][:20])
            new_post.user = request.user
            new_post.save()
            messages.success(request, 'you created a new post', 'success')
            return redirect('post:post-detail', new_post.id, new_post.slug)
        return render(request, 'post/create.html', {'form': form})

But you are implementing a lot of boilerplate code here. What you here do is implementing a CreateView [Django-doc]:

from django.contrib.messages.views import SuccessMessageMixin
from django.views.generic import CreateView


class PostCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView):
    form_class = PostCreateUpdateForm
    template_name = 'post/create.html'
    success_message = 'you created a new post'

    def form_valid(self, form):
        form.instance.slug = slugify(form.cleaned_data['body'][:20])
        form.instance.user = request.user
        return super().form_valid()

    def get_success_url(self):
        return reverse('post:post-detail', args=(new_post.id, new_post.slug))

CodePudding user response:

Your "post" method in PostCreateView only returns a response if the form is valid. If it isn't valid, it will return None, causing an error.

Modify that method so it looks like this:

    def post(self, request, *args, **kwargs):
        form = self.form_class(request.POST)
        if form.is_valid():
            new_post = form.save(commit=False)
            new_post.slug = slugify(form.cleaned_data["body"][:20])
            new_post.user = request.user
            new_post.save()
            messages.success(request, "you created a new post", "success")
            return redirect("post:post-detail", new_post.id, new_post.slug)
        return render(request, "post/create.html", {"form": form})
  • Related