删除前编辑记录。 Django DeleteView

时间:2018-11-04 20:42:56

标签: python django django-models django-forms django-views

我有以下型号:

class Category(models.Model):
    ....
    posts = models.PositiveIntegerField(_('numero post'), default=0)
    ....

class Post(models.Model):
    ....
    categories = models.ManyToManyField(Category, blank=True, verbose_name=_('categorie'))
    ....

Category.posts字段计算与其自身类别相关的帖子数。我通过以下方式将计数器增加到CreateView中:

class CreatePostView(LoginRequiredMixin, CreateView):
    model = Post
    ...

    def form_valid(self, form, **kwargs):
        ...
        categories = self.object.categories.all()
        for category in categories:
            category.posts = category.posts + 1
            category.save()

        self.object.save()
        return super(CreatePostView, self).form_valid(form)

当我删除博客帖子时,Post被删除时我需要减少计数器。我尝试过这种方式:

class DeletePostView(LoginRequiredMixin, DeleteView):
    model = Post
    ...

    def form_valid(self, form, **kwargs):
        ...
        categories = post.categories.all()
        for category in categories:
            if (category.posts - 1) > 0:
                category.posts = category.posts - 1
                category.save()
        return post

但是它不起作用,因为在调用此方法之前记录已被删除。

在删除记录之前,我该怎么做? 还是有一种内置的方法可以从Category获取相关记录的数量?

1 个答案:

答案 0 :(得分:0)

form_valid没有DeleteView,因为DeleteView没有格式。

我们可以做的是在.delete(..)函数中添加一些逻辑,该函数将删除对象。 DeleteView将其实现为:

def delete(self, request, *args, **kwargs):
    """
    Call the delete() method on the fetched object and then redirect to the
    success URL.
    """
    self.object = self.get_object()
    success_url = self.get_success_url()
    self.object.delete()
    return HttpResponseRedirect(success_url)

因此我们可以将其实现为:

from django.db.models import F

class DeletePostView(LoginRequiredMixin, DeleteView):

    model = Post
    # ...

    def delete(self, *args, **kwargs):
        self.object = self.get_object()
        self.object.post.categories.all().update(posts=F('posts')-1)
        return super(DeletePostView, self).delete(*args, **kwargs)

以上内容将通过减少posts字段来更新“批量”中的类别。但是,它可以达到零(在您的给定代码中这是不可能的)。

如果您想避免这种情况,我们可以使用Greatest [Django-doc]来避免这种情况:

from django.db.models import F, Value
from django.db.models.functions import Greatest

class DeletePostView(LoginRequiredMixin, DeleteView):

    model = Post
    # ...

    def delete(self, *args, **kwargs):
        self.object.post.categories.all().update(posts=Greatest(F('posts')-1, Value(1)))
        return super(DeletePostView, self).delete(*args, **kwargs)