The*_*Hog 7 python django django-models
我试图在django manager(models.Manager)上重写get_by_natural_key方法.添加模型(NexchangeModel)后,我可以删除所有()对象,但单个 - 不能.
能够:
SmsToken.objects.all().delete()
Run Code Online (Sandbox Code Playgroud)
不能:
SmsTokent.objects.last().delete()
Run Code Online (Sandbox Code Playgroud)
码:
from django.db import models
from core.common.models import SoftDeletableModel, TimeStampedModel, UniqueFieldMixin
class NexchangeManager(models.Manager):
def get_by_natural_key(self, param):
qs = self.get_queryset()
lookup = {qs.model.NATURAL_KEY: param}
return self.get(**lookup)
class NexchangeModel(models.Model):
class Meta:
abstract = True
objects = NexchangeManager()
class SmsToken(NexchangeModel, SoftDeletableModel, UniqueFieldMixin):
sms_token = models.CharField(
max_length=4, blank=True)
user = models.ForeignKey(User, related_name='sms_token')
send_count = models.IntegerField(default=0)
Run Code Online (Sandbox Code Playgroud)
在调用时:
SmsToken.objects.all().delete()您正在调用queryset的delete方法.
但是SmsTokent.objects.last().delete()你正在调用实例的删除方法.
在django 1.9 queryset delete方法之后返回没有删除的项目.REF
在Django 1.9中更改:添加了描述已删除对象数的返回值.
但是在实例delete方法上,Django已经知道只会删除一行.
另请注意,querset的delete方法和实例的delete方法不同.
delete()
[on a querset]方法执行批量删除,不会在模型上调用任何delete()方法[instance method].但是,它会为所有已删除的对象(包括级联删除)发出pre_delete和post_delete信号.
因此,您不能依赖该方法的响应来检查删除是否正常.但就蟒蛇的哲学而言"要求宽恕而非许可".这意味着您可以依赖异常来查看删除是否以其应有的方式正常工作.Django的ORM将引发适当的异常并在发生任何故障时进行适当的回滚.
所以你可以这样做:
try:
instance.delete()/querset.delete()
except Exception as e:
# some code to notify failure / raise to propagate it
# you can avoid this try..except if you want to propagate exceptions as well.
Run Code Online (Sandbox Code Playgroud)
注意:我正在捕获泛型异常,因为我的try块中唯一的代码是delete.如果您希望使用其他代码,则必须仅捕获特定的例外.
我假设它SoftDeletableModel来自django-model-utils包?如果是这样,该模型的目的是使用is_removed字段标记实例而不是实际删除它们.因此,可以预期调用delete()模型实例 - 这是你得到的last()- 实际上不会删除任何东西.
SoftDeletableModel 提供一个objects属性,其中一个管理器将其结果限制为未删除的对象,并覆盖delete()将对象标记为已删除而不是实际删除它们.
问题是您已将自己的经理定义为objects,因此SoftDeletableModel经理未被使用.您的自定义管理器实际上是从数据库中批量删除对象,这与执行软删除的目标相反.解决此问题的方法是让您的自定义管理器继承自SoftDeletableManagerMixin:
class NexchangeManager(SoftDeletableManagerMixin, models.Manager):
# your custom code
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
993 次 |
| 最近记录: |