django 如果post方法未被覆盖,则未调用form_valid方法

qojgxg4l  于 2023-05-08  发布在  Go
关注(0)|答案(1)|浏览(188)

我有一个博客,是由用户的帖子和帖子的评论。在我的UpdateView中,模型指向Post,所以我可以在模板中显示帖子。在我的form_valid方法中,我通过一个表单从用户那里获取评论。问题是,如果我不覆盖post方法,就不会调用form_valid方法。当我通过表单发布内容时,会发生什么?django调用了哪些方法,我应该覆盖哪些方法?

class PostDetails(UpdateView):

    template_name = "posts/details.html"
    model = Post
    form_class = CommentForm
    context_object_name = 'post'
    # success_url = "posts/details.html"

    def form_valid(self, form):
        post = self.get_object()
        comments = Comments(**form.cleaned_data)
        comments.post = Post(post.id)

        if self.request.user.is_authenticated:
            comments.user = self.request.user

        comments.save()
        messages.success(self.request, "Post sent successfully")
        return redirect("posts:details", pk=post.id)

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        post = self.get_object()
        comments = Comments.objects.filter(published=True,
                                           post=post.id)
        context['comments'] = comments

        return context
class CommentForm(ModelForm):

    def clean(self):
        data = super().clean()
        author = data.get("author")
        comment = data.get("comment")

        if len(comment) < 15:
            print("Entrou no if do comment")
            self.add_error("comment", "Comment must be 15 chars or more.")
        if len(author) < 5:
            self.add_error("author", "Field must contain 5 or more letters.")

    class Meta:
        model = Comments
        fields = ['author', 'email', 'comment']
{% extends 'base.html' %}
{% load user_is_none %}
{% block post_content %}

    <div class="row pt-5">
        <div class="col-xl"></div>
        <div class="col-xl-8 text-center">
            <h2>{{ post.title | safe}}</h2>
            <h5>{{ post.excerpt | safe}}</h5>
            <p class="text-muted mt-4">
                <small>
                    {{  post.author | user_not_defined}} {{ post.date}} | {{ post.category}}
                </small>
            </p>
        </div>
        <div class="col-xl"></div>
    </div>

    <div class="row pt-5">
        <div class="col-xl"></div>
        <div class="col-xl-8">

            {% if post.image %}
                <img class="img-fluid pb-5 " src="{{ post.image.url }}" alt="{{ post.title }}">
            {% endif %}

            {{ post.content|safe }}

        </div>
        <div class="col-xl"></div>
    </div>

    <div class="row pt-5">

    </div>
    <div class="col-xl"></div>
    <div class="row pt-5">
            <div class="col-xl"></div>
            <div class="col-xl-8">
                <h2 class="my-3">Comments ({{ comments.count }})</h2>

                {% for comment in comments %}
                <h5 class="mb-2 mt-5">{{ comment.author }} said:</h5>
                <small class="text-muted">{{ comment.data }}</small>
                <p class="mb-1">{{ comment.comment | safe }}</p>
                {% endfor %}

            </div>
            <div class="col-xl"></div>
        </div>
    <div class="row pt-5">
        <div class="col-xl"></div>
        <div class="col-xl-8">
            <h2 class="my-3">Type your message</h2>
            <form method="POST">
                {% csrf_token %}
                {% include 'partial/messages/_messages.html' %}
                <table class="table">
                    {{ form }}
                    <tr>
                        <td colspan="2">
                            <input id="envia_comentario" type="submit" class="btn btn-primary"                  value="Enviar">
                        </td>
                    </tr>
                </table>
            </form>
            </table>

        </div>
        <div class="col-xl"></div>
    </div>
{% endblock %}

我试着在代码中加入post方法。在此之后,调用了form_valid。

class PostDetails(UpdateView):

    template_name = "posts/details.html"
    model = Post
    form_class = CommentForm
    context_object_name = 'post'
    # success_url = "posts/details.html"

    def post(self, request, *args, **kwargs):
        form = self.get_form()
        if form.is_valid():
            return self.form_valid(form)
        else:
            return self.form_invalid(form)

    def form_invalid(self, form):
        post = self.get_object()
        print(post)
        return render(self.request, "posts/details.html", {"form": form, "post": post})

    def form_valid(self, form):
        post = self.get_object()
        comments = Comments(**form.cleaned_data)
        comments.post = Post(post.id)

        if self.request.user.is_authenticated:
            comments.user = self.request.user

        comments.save()
        messages.success(self.request, "Post sent successfully")
        return redirect("posts:details", pk=post.id)

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        post = self.get_object()
        comments = Comments.objects.filter(published=True,
                                           post=post.id)
        context['comments'] = comments

        return context
from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
from category.models import Category

class Post(models.Model):

    title = models.CharField(max_length=200)
    author = models.ForeignKey(User, on_delete=models.DO_NOTHING, 
    null=True, blank=True)
    date = models.DateTimeField(default=timezone.now)
    content = models.TextField()
    excerpt = models.TextField()
    category = models.ForeignKey(Category,   
    on_delete=models.DO_NOTHING)
    image = models.ImageField(upload_to='image/%Y/%m/%d')
    published = models.BooleanField(default=False)

    def __str__(self):
        return self.title
from django.db import models
from posts.models import Post
from django.utils import timezone
from django.contrib.auth.models import User

class Comments(models.Model):

    author = models.CharField(max_length=100, blank=False)
    email = models.EmailField(max_length=100, blank=False)
    comment = models.TextField(blank=False, max_length=100)
    post = models.ForeignKey(Post, on_delete=models.CASCADE,  
    blank=False, related_name='comments')
    data = models.DateTimeField(blank=False, default=timezone.now)
    user = models.OneToOneField(User, 
    blank=True,on_delete=models.DO_NOTHING, null=True)
    published = models.BooleanField(default=False, blank=False)

    def __str__(self):
        return self.author
yruzcnhs

yruzcnhs1#

您的clean方法应该返回清理后的数据,但在本例中,您进行了两次单独的清理,因此您可以使用:

from django.core.exceptions import ValidationError

from django import forms

class CommentForm(forms.ModelForm):
    def clean_author(self):
        author = self.cleaned_data['author']
        if len(author) < 5:
            raise ValidationError('Field must contain 5 or more letters.')
        return author

    def clean_comment(self):
        comment = self.cleaned_data['comment']
        if len(comment) < 15:
            raise ValidationError('Comment must be 15 chars or more.')
        return comment

    class Meta:
        model = Comments
        fields = ['author', 'email', 'comment']

至于视图,您实现了太多的样板代码,并且通过使用UpdateView,它不会创建注解,它只会尝试 * 更新 * Post
您可以使用CreateView

from django.contrib.messages.views import SuccessMessageMixin
from django.shortcuts import get_object_or_404
from django.views.generic.edit import CreateView

class PostDetails(SuccessMessageMixin, CreateView):
    template_name = 'posts/details.html'
    form_class = CommentForm
    success_message = 'Post sent successfully'

    def get_success_url(self):
        return redirect('posts:details', pk=self.kwargs['pk'])

    def form_valid(self, form):
        form.instance.post_id = self.kwargs['pk']
        if self.request.user.is_authenticated:
            form.instance.user = self.request.user
        return super().form_valid(form)

    def get_context_data(self, **kwargs):
        post = get_object_or_404(Post, pk=self.kwargs['pk'])
        return super().get_context_data(
            **kwargs, post=post, comments=post.comments_set.filter(published=True)
        )

相关问题