mas*_*ing 5 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'))
....
Run Code Online (Sandbox Code Playgroud)
该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)
Run Code Online (Sandbox Code Playgroud)
当我删除博客文章时,我需要在删除博客文章时减少计数器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
Run Code Online (Sandbox Code Playgroud)
但它不起作用,因为在调用此方法之前记录已被删除。
在删除记录之前如何进行此操作?或者有一种内置的方法可以从中获取相关记录的数量Category?
form_valid由于a没有形式DeleteView,因此 a不存在DeleteView。
我们能做的就是在.delete(..)函数中添加一些逻辑,也就是删除对象的函数。将其DeleteView实现为:
Run Code Online (Sandbox Code Playgroud)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)Run Code Online (Sandbox Code Playgroud)
上面的代码将通过减少字段来“批量”更新类别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)Run Code Online (Sandbox Code Playgroud)
小智 5
在 4.0 版本中,您将收到警告DeleteViewCustomDeleteWarning:DeleteView 使用 FormMixin 处理 POST 请求。因此,YourDeleteView.delete() 处理程序中的任何自定义删除逻辑都应移至 form_valid()。所以,继续在 form_valid 中实现你的逻辑
| 归档时间: |
|
| 查看次数: |
4310 次 |
| 最近记录: |