python - 删除前编辑记录。 Django 删除 View

标签 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 中获取相关记录的数量?

最佳答案

DeleteView 没有 form_valid,因为 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 <b>delete</b>(self, *args, **kwargs):
        self.object = self.get_object()
        <b>self.object.post.categories.all().update(posts=F('posts')-1)</b>
        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 <b>delete</b>(self, *args, **kwargs):
        <b>self.object.post.categories.all().update(posts=Greatest(F('posts')-1, Value(1)))</b>
        return super(DeletePostView, self).delete(*args, **kwargs)

关于python - 删除前编辑记录。 Django 删除 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53145279/

相关文章:

Python:创建列表列表作为字典值

python - 连续多处理

python - 如何为 Django 创建一个唯一的随机用户名?

Django 部分更新

python - 按子字符串条件过滤 pandas DataFrame

python - 在 Mac 上使用 Python 3.5.0 + Sublime 3.0 运行代码

Python - 使用 auth.User 模型作为 OneToOneField 的 Django 查询

python - Django 测试并行 AppRegistryNotReady

python - Django中的多态模型继承

django - 如何在 ModelForm 中指定 Select 和 RadioSelect?