有没有办法覆盖 Django 中的模型方法?

is there a way to override model methods in django?

我有这样一个模型:

class Car(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4)
    create_date = models.DateTimeField('date added', auto_now_add=True)
    modify_date = models.DateTimeField('date modified', auto_now=True)
    ...

    def last_tracked_location(self):
        ...
        try:
            url = 'myurl'
            return requests.get(
                url,
            ).json()['location'])
        except:
            return False

稍后会为管理员面板调用此方法。它从 api 然后 returns 请求一些东西,要么是这个要么是假的。

在测试模式下,另一个 api 不存在,因此请求延迟所有测试直到超时,然后 returns False

有没有办法覆盖它?我检查了 docs 但只能找到覆盖设置。

我的另一个想法是在方法内部测试它是否在测试模式下被调用,然后永远不要进入这个 try 块。但我不认为这是一种干净的方式。

更新

我这样调用测试:

python3 manage.py test --settings=app.settings_test

您可以编写测试以模拟 API 的响应。 unittest mock 模块是一个很好的起点,也是 Python 标准库的一部分,因为 Python 3.3.

我无法访问您的完整代码,但这里有一个帮助您入门的示例:

from unittest import mock
from django.test import TestCase
from .models import Car


@mock.patch('yourapp.models.Car.last_tracked_location')
class CarTestCase(TestCase):
    def test_get_last_tracked_location(self, mock_last_tracked_location):
        mock_last_tracked_location.return_value = {'location': 'Paris'}
        car = Car.objects.create()
        response = car.last_tracked_location()
        assert response['location'] == 'Paris'

在我看来,直接在方法中检查 DEBUG 不是很干净。 也许你写一些 API class 来提出这个要求会更好?

然后你可以在 'testing mode' 中为这个 class 到 运行 编写单独的逻辑(不确定我是否正确理解你的意思:) test env?)或者只需在测试中创建模拟。

您可以在此处阅读有关条件测试场景的更多信息: https://realpython.com/testing-third-party-apis-with-mocks/