我正在尝试使用Django的AppConfig.ready()
方法在其中一个模型上运行一些查询来检索一些数据。
下面的代码:
class NewsConfig(AppConfig):
name = "apps.news"
verbose_name = "News"
def ready(self):
NewsType = self.models.get("newstype")
NewsType.names = NewsType.objects.values_list("name", flat=True)
然后,在urls.py
上,我使用它们如下:
news_type_names_regex = generate_regex(NewsType.names)
router = DefaultRouter()
router.register(r'news/' + news_type_names_regex, NewsModelViewSet, basename='news')
当应用程序运行时(使用uvicorn或runserver),这工作正常,但当运行测试时,AppConfig.ready()
在迁移运行之前被执行,这导致以下错误:
...
django.db.utils.OperationalError: no such table: news_newstype
我已经阅读了文档中的警告,但我不认为它与这个问题有关。我在AppConfig.ready()
上这样做的原因是因为它需要在django.setup()
之后的某个地方完成,而不是在异步请求上下文中(因为我正在使用django通道并运行应用程序ASGI)。
1条答案
按热度按时间shyt4zoc1#
解释
这在应用程序运行时(使用uvicorn或runserver)工作正常,但在运行测试时,AppConfig.ready()会在迁移运行之前执行。
这是完全正确的,服务器运行正常的原因是
news_newstype
表已经存在,因为创建该表的迁移已经应用。但是,在运行测试时,迁移会在运行测试之前运行,并且由于测试数据库中尚未创建表
news_newstype
,因此会导致错误。溶液
您应该删除从数据库值生成的动态URL路径,并避免代码引用
NewsConfig.ready()
中的数据库表。相反,您可以使用URL参数捕获,并使用捕获的值在视图方法中搜索数据库。
urls.py
然后在视图方法中使用捕获的
news_type
参数注解
这只是一个
generics.GenericAPIView
的例子,如果你想使用viewset,请阅读restframework文档。另外,你可以在django文档中找到关于URL参数捕获的文档。