代码之家  ›  专栏  ›  技术社区  ›  Jasper

具有覆盖“delete”方法的模型的Django test deleteview

  •  1
  • Jasper  · 技术社区  · 7 年前

    我正在为包含多个deleteviews的django应用程序编写测试。我使用以下代码的变体测试所有DeleteView:

    #Object exists to begin with
    response = self.client.get(reverse('roldelete', kwargs={'pk': self.role.pk}))
    self.assertEqual(response.status_code, 200)
    
    #Object Can be deleted can be posted
    response = self.client.post(reverse('roldelete', kwargs={'pk': self.role.pk}))
    self.assertEqual(response.status_code, 302)
    
    #Object is actually deleted
    response = self.client.get(reverse('roldelete', kwargs={'pk': self.role.pk}))
    self.assertEqual(response.status_code, 404)
    
    #Query returns an empty result
    self.assertFalse(Role.objects.filter(pk=self.role.pk).exists())
    

    所有这些都很好,但是,在我的一个模型中,我覆盖了默认的“delete”方法。基本上,每次我删除“TenantPurchase”对象时,我都想检查是否存在链接的“PurchaseRequest”对象,并将其删除。为此,我在TenantPurchase模型中编写了以下代码:

    def delete(self, *args, **kwargs):
        try:
    
            purchase_user = self.user
            purchase_arrangement_period = self.item
    
            #Import here to avoid circular import
            from arrangement.models import ArrangementBuyRequest
    
            linked_buy_request = ArrangementBuyRequest.objects.filter(
                user=purchase_user,
                arrangement_period=purchase_arrangement_period) \
                .order_by('request_date').last()
    
            linked_buy_request.delete()
        except (ArrangementBuyRequest.DoesNotExist, AttributeError) as e:
            pass
    
        super(TenantPurchase, self).delete(*args, **kwargs)
    

    然而,我对这个模型的所有单元测试都失败了。 它通过了前三个测试(assert 200、assert 302、assert 404)

    self.assertFalse(
            TenantPurchase.objects.filter(tenant=self.tenant, user=self.user, item_id=self.period.pk).exists())
    
    
    Traceback (most recent call last):
    (...), line 105, in test_linked_request_deleted
    
    self.assertFalse(ArrangementBuyRequest.objects.filter(user=self.user,         arrangement_period=self.period).exists())
    AssertionError: True is not false
    

    链接的购买请求同上:

    # Check if the related buyrequest has been deleted as well
        self.assertFalse(ArrangementBuyRequest.objects.filter(user=self.user, arrangement_period=self.period).exists())
    
    Traceback (most recent call last):
    (...), line 80, in test_tenant_purchase_deleted
    TenantPurchase.objects.filter(tenant=self.tenant, user=self.user, item_id=self.period.pk).exists())
    AssertionError: True is not false
    

    由于这种情况与所有其他(通过的)测试之间的唯一区别是模型中覆盖的“delete”方法,因此问题可能来自该部分(可能在测试中没有正确加载) 但是我找不到导致测试失败的错误。在我们的开发服务器上一切都很好,这对我们没有帮助,很难找出错误。

    有人知道我错过了什么吗?

    1 回复  |  直到 7 年前
        1
  •  1
  •   mKane848    6 年前

    在拍摄我自己的一些问题时偶然发现了这一点,我只是想告诉你 this answer . 当通过QuerySet操作删除对象时(也称为任何批量操作、从管理中删除所有对象等),Django不调用模型删除函数,而是直接与表交互。链接的答案提供了一个关于如何绕过这个问题的示例,看起来它可能就是您正在/正在寻找的。