Django - 使用 drf-nested-routers 反向嵌套 url

     2023-02-24     55

关键词:

【中文标题】Django - 使用 drf-nested-routers 反向嵌套 url【英文标题】:Django - reverse nested url with drf-nested-routers 【发布时间】:2020-11-15 08:15:30 【问题描述】:

我将我的 api url 配置为

localhost:port/app_name/students/student_id/macro/macro_id/lto

使用 drf-nested-routers 扩展。基本上,每个学生都分配了一些宏观类别,这些类别又具有一些长期目标 (LTO)。我已经使用 curlPostman 对其进行了测试,一切似乎都正常。 现在我需要为我的 LTO 模型编写一个更精确的测试用例。 这是我的 urls.py

from django.urls import path, re_path
from django.conf.urls import include
from rest_framework import routers
from app_name.views.views import UserViewSet, StudentViewSet, MacroViewSet, LTOViewSet, MacroAssignmentViewSet
from rest_framework_nested import routers as nested_routers

# application namespace
app_name = 'app_name'

router = routers.DefaultRouter()
router.register(r'users', UserViewSet, basename='user')
router.register(r'macro', MacroViewSet, basename='macro')
router.register(r'macro-assignments', MacroAssignmentViewSet, basename='macro-assignment')

student_router = routers.DefaultRouter()
student_router.register(r'students', StudentViewSet, basename='student')
lto_router = nested_routers.NestedSimpleRouter(student_router, r'students', lookup='student')
lto_router.register(r'macro/(?P<macro_pk>.+)/lto', LTOViewSet, basename='lto')


urlpatterns = [
    re_path('^', include(router.urls)),
    re_path('^', include(student_router.urls)),
    re_path('^', include(lto_router.urls)),
]

问题是我无法正确使用 reverse() 方法来获取我的 LTOViewSet 的 url 来测试它。

self.url = reverse('app_name:student-detail:lto', getattr(self.student, 'id'), getattr(self.macro, 'id'))

这会产生以下错误

django.urls.exceptions.NoReverseMatch: 'student-detail' is not a registered namespace inside 'app_name'

在其他测试用例中,我使用非常相似的句子并且效果很好

self.list_url = reverse('app_name:student-list')

reverse('app_name:student-detail', post_response.data['id'])

【问题讨论】:

旁注:您不必多次创建routers.DefaultRouter 对象 @ArakkalAbu 即使我不想让student_router'urls 嵌套在router 中? 那么知道URL namespaces 是什么,对您有帮助吗?您正在尝试按您尚未创建的命名空间引用 lto。 @Melvyn 据我了解,每个 namespace 对应一个 app_name。我将所有东西都放在一个应用程序中,所以我不应该使用其他命名空间 错误消息和反向调用不匹配:reverse('app_name:student-detail:lto'Reverse for 'student-detail-lto'。参见冒号与 -。那么这两者中的哪一个呢? 【参考方案1】:

所以这里是最小可重复的例子:

# main/viewsets.py
from rest_framework.viewsets import ModelViewSet
from django.contrib.auth.models import User, Group


class StudentViewSet(ModelViewSet):
    model = User


class LTOViewSet(ModelViewSet):
    model = Group
# main/urls.py
from django.urls import re_path, include
from rest_framework import routers

from rest_framework_nested import routers as nested_routers
from .viewsets import StudentViewSet, LTOViewSet

# application namespace
app_name = "main"

student_router = routers.DefaultRouter()
student_router.register(r"students", StudentViewSet, basename="student")
lto_router = nested_routers.NestedSimpleRouter(
    student_router, r"students", lookup="student"
)
lto_router.register(r"macro/(?P<macro_pk>.+)/lto", LTOViewSet, basename="lto")

urlpatterns = [
    re_path("^", include(student_router.urls)),
    re_path("^", include(lto_router.urls)),
]
reverse('main:lto-detail', args=(1,1,1))
Out[5]: '/api/students/1/macro/1/lto/1/'

所以确实你的错误只是传递了路由器基名而不是最终端点来反转,并且由于嵌套我们被学生详细信息不反转(我仍然不明白)抛出。

【讨论】:

student-detail 不需要手动反转。一旦 Django 知道最终端点(在本例中为“lto-detail/list”),他就会自动反转整个嵌套的 url。他唯一需要的是 url 中的参数 --> 在这种情况下是学生和宏的主键 啊,我现在明白了……当您更新错误消息时,它抱怨的是命名空间,而不是 url 名称了。现在一切都说得通了!

使用 Django 模板和标签而不使用 Django 的其余部分

】使用Django模板和标签而不使用Django的其余部分【英文标题】:UseDjangotemplatesandtagswithouttherestofDjango【发布时间】:2016-03-0619:20:00【问题描述】:我想使用Django进行模板化,但我没有构建网络应用程序。基本上,我的大部分问题... 查看详情

使用 django.contrib.messages 重定向 Django 注册激活

】使用django.contrib.messages重定向Django注册激活【英文标题】:Django-RegistrationActivationredirectwithdjango.contrib.messages【发布时间】:2012-05-0818:15:08【问题描述】:我正在尝试设置我的django-registration激活工作流程,以便当用户点击激活... 查看详情

使用 azure 作为 Django 的存储后端(使用 django-storages)

】使用azure作为Django的存储后端(使用django-storages)【英文标题】:UsingazureasastoragebackendforDjango(usingdjango-storages)【发布时间】:2016-01-1402:26:54【问题描述】:我正在使用django-storages,我过去曾用它来处理AWSS3。但是在使用MicrosoftA... 查看详情

在 Django 之外使用 Django ORM

】在Django之外使用DjangoORM【英文标题】:UseDjangoORMoutsideofDjango【发布时间】:2018-01-1715:25:33【问题描述】:我是Django新手,想在我的脚本中使用它的ORM,而不需要运行整个Django。我正在摸索如何配置它。在***上的搜索没有帮助,... 查看详情

Django - 使用 django-mailer 发送批量邮件

】Django-使用django-mailer发送批量邮件【英文标题】:Django-SendingBulkMailsusingdjango-mailer【发布时间】:2011-05-0810:12:58【问题描述】:我正在使用django-mailer发送电子邮件。我有cron作业每分钟从队列中发送邮件。我使用GMail的SMTP服务器... 查看详情

Django:使用 Django ORM 实现 JOIN?

】Django:使用DjangoORM实现JOIN?【英文标题】:Django:implementingJOINusingDjangoORM?【发布时间】:2011-05-0617:44:01【问题描述】:我有一个用Django构建的问答类型的网站,具有以下模型:classQuestion(models.Model):title=models.CharField(max_length=70)d... 查看详情

使用 Django 模板标签的 Mako 模板

】使用Django模板标签的Mako模板【英文标题】:MakotemplatesusingDjangotemplatetags【发布时间】:2011-04-1623:49:23【问题描述】:我们的Django站点是使用Mako模板构建的。我们想使用一个名为django-socialregistration的第三方项目,但它的模板标... 查看详情

使用django返回helloworld(代码片段)

文章目录使用Django返回helloworld一,Django的版本二,新建Django项目三,代码修改四,测试五,总结使用Django返回helloworld一,Django的版本安装Django直接使用pipinstalldjango命令安装即可。下面进入terminal查下我电... 查看详情

如何在 Django 之外使用 Django 模型?

】如何在Django之外使用Django模型?【英文标题】:HowtouseDjangomodelsoutsideofDjango?【发布时间】:2019-08-1009:16:26【问题描述】:按照this指南,我可以通过调用pythonmain.py来使用具有以下文件结构的Django之外的模型。├──data│├──... 查看详情

如何使用 django 编写代码 [关闭]

】如何使用django编写代码[关闭]【英文标题】:howtowritecodesusingdjango[closed]【发布时间】:2014-02-0509:58:51【问题描述】:如何在ubuntu平台上使用django框架编写python代码。也可以在windows平台上使用django来编写python代码吗?django可以... 查看详情

使用 Django/Django.js 和 WSGIScriptAlias 进行 URL 反向

】使用Django/Django.js和WSGIScriptAlias进行URL反向【英文标题】:URLReversewithDjango/Django.jsandWSGIScriptAlias【发布时间】:2014-12-2810:58:08【问题描述】:我在生产环境中的django项目有问题。当我为“WSGIScriptAlias”apache指令使用别名时,看... 查看详情

使用django的环境变量

在一个py文件中使用django的环境变量importosif__name__==‘__main__‘:‘‘‘‘在一个py文件中使用django的环境变量‘‘‘os.environ.setdefault("DJANGO_SETTINGS_MODULE","aboutdrf.settings")importdjangodjango.setup() 查看详情

django使用小结

一、静态文件的使用二、csrf跨站访问安全机制设置三、MODEL模型使用 查看详情

使用 django.template 时出错

】使用django.template时出错【英文标题】:Errorwhenusingdjango.template【发布时间】:2013-08-0712:43:10【问题描述】:我是django的初学者,在使用django的模板模块时遇到了很多错误。以下工作来自pythonshell:fromdjangoimporttemplatet=template.Templa... 查看详情

[oldboy-django][2深入django]django模板使用函数

1模板引入子html--include7模板引擎-母版-include,导入公共的htmla.用法:{%include"pub.html"%},pub.html还可以添加{{name}}b.一个页面可以导入多次,一个html只能有一个母版c.样例#public.html<divclass="public"><divclass="content">{{userinfo}}&l 查看详情

Django:当我使用 django 表单时,如何实现这个 html 表单

】Django:当我使用django表单时,如何实现这个html表单【英文标题】:Django:howcanIachievethishtmlformwhenIworkwithdjangoforms【发布时间】:2018-09-2323:18:19【问题描述】:我需要做到以下几点:<inputtype="text"name="montantHTvente.id"value="vente.monta... 查看详情

web框架django使用概览(代码片段)

Web框架Django使用概览标签:djangopython1开始一个新项目django的安装比较简单,在命令行里执行下面的命令。pipinstalldjango为了能使用django已有的模板代码,需要使用django-admin命令来执行诸如创建项目,创建项目下的... 查看详情

django如何使用模板

】django如何使用模板【英文标题】:djangohowtoworkwithtemplates【发布时间】:2011-06-0416:06:51【问题描述】:我现在正在练习Django,但我被困住了。当我跑步时:>>>fromdjangoimporttemplate>>>t=template.Template(\'hi\')给我:ImportError... 查看详情