我有以下型号:
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
获取相关记录的数量?
答案 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)