添加时的 Django 管理模型无法呈现相关更改 link
Django Admin Model on add fails to render related change link
给定以下管理设置:
class BrokerLocationSetForm(forms.ModelForm):
class Meta:
model = BrokerLocationSet
fields = ('broker', 'program', 'label', 'locations')
widgets = {
'locations': autocomplete.ModelSelect2Multiple(url='admin-autocomplete-location', forward=('broker','program')),
}
class BrokerLocationSetAdmin(admin.ModelAdmin):
model = BrokerLocationSet
form = BrokerLocationSetForm
list_display=['broker', 'program', 'label']
admin.site.register(BrokerLocationSet, BrokerLocationSetAdmin)
当我尝试在管理中为 BrokerLocationSetForm 导航添加视图时,它引发了以下错误:
raise NoReverseMatch(msg) NoReverseMatch: Reverse for 'program_program_change' with arguments '(u'__fk__',)' not found. 1 pattern(s) tried: [u'admin/program/program/(?P<program_pk>\d+)/change/$']
当我在 shell 中调试时:
reverse('admin:broker_broker_change', 'myapp.urls', args=(u'__fk__',))
它输出:
u'/admin/broker/broker/fk/change/'
但对于:
reverse('admin:program_program_change', 'myapp.urls', args=(u'__fk__',))
我得到与上面相同的错误。经过一些调试后,我感觉到管理员以某种方式将一个字符串而不是一个 int 传递给反向函数,而它期望一个整数,如下所示:
reverse('admin:program_program_change', 'myapp.urls', args=(u'1',))
u'/admin/program/program/1/change/'
由于 django 管理员这样做 url reversing magic 我不确定我应该在哪里自定义它来修复错误。我已经有了这个相当新的代码库并且完全理解了。
如何通过自定义管理模型或表单来修复上述错误。我不想更新 'admin:program_program_change' 但可能会提供通往相同视图的替代路线! .可能吗 ?请指教!
我找到了一个解决方案,但是我不确定这是否是最好的解决方案。由于 ProgramAdmin
需要一个数字参数,而 BrokerLocationSetAdmin
的弹出窗口 link 需要一个带有字符串参数的路由。例如
reverse('admin:program_program_change', 'myapp.urls', args=(u'__fk__',))
解决方案是通过覆盖其 get_urls
方法,将另一个具有相同名称的管理路由注入 ProgramAdmin
模型,如下所示:
class ProgramAdmin(admin.ModelAdmin):
...
...
def get_urls(self):
from django.conf.urls import url
from functools import update_wrapper
def wrap(view):
def wrapper(*args, **kwargs):
return self.admin_site.admin_view(view)(*args, **kwargs)
wrapper.model_admin = self
return update_wrapper(wrapper, view)
urls = super(ProgramAdmin, self).get_urls()
info = self.model._meta.app_label, self.model._meta.model_name
alt_urls=[
url(r'^(?P<program_pk>\w+)/change/$', wrap(self.change_view), name='%s_%s_change' % info),
]
return urls+alt_urls
现在我们有两个名称相同但路径参数不同的路由例如:
/admin/program/program/<program_pk>/change/ django.contrib.admin.options.change_view admin:program_program_change
admin/program/program/(?P\d+)/change/$
/admin/program/program/<program_pk>/change/ django.contrib.admin.options.change_view admin:program_program_change
admin/program/program/(?P\w+)/change/$
根据上下文,将使用路由之一。
给定以下管理设置:
class BrokerLocationSetForm(forms.ModelForm):
class Meta:
model = BrokerLocationSet
fields = ('broker', 'program', 'label', 'locations')
widgets = {
'locations': autocomplete.ModelSelect2Multiple(url='admin-autocomplete-location', forward=('broker','program')),
}
class BrokerLocationSetAdmin(admin.ModelAdmin):
model = BrokerLocationSet
form = BrokerLocationSetForm
list_display=['broker', 'program', 'label']
admin.site.register(BrokerLocationSet, BrokerLocationSetAdmin)
当我尝试在管理中为 BrokerLocationSetForm 导航添加视图时,它引发了以下错误:
raise NoReverseMatch(msg) NoReverseMatch: Reverse for 'program_program_change' with arguments '(u'__fk__',)' not found. 1 pattern(s) tried: [u'admin/program/program/(?P<program_pk>\d+)/change/$']
当我在 shell 中调试时:
reverse('admin:broker_broker_change', 'myapp.urls', args=(u'__fk__',))
它输出:
u'/admin/broker/broker/fk/change/'
但对于:
reverse('admin:program_program_change', 'myapp.urls', args=(u'__fk__',))
我得到与上面相同的错误。经过一些调试后,我感觉到管理员以某种方式将一个字符串而不是一个 int 传递给反向函数,而它期望一个整数,如下所示:
reverse('admin:program_program_change', 'myapp.urls', args=(u'1',))
u'/admin/program/program/1/change/'
由于 django 管理员这样做 url reversing magic 我不确定我应该在哪里自定义它来修复错误。我已经有了这个相当新的代码库并且完全理解了。
如何通过自定义管理模型或表单来修复上述错误。我不想更新 'admin:program_program_change' 但可能会提供通往相同视图的替代路线! .可能吗 ?请指教!
我找到了一个解决方案,但是我不确定这是否是最好的解决方案。由于 ProgramAdmin
需要一个数字参数,而 BrokerLocationSetAdmin
的弹出窗口 link 需要一个带有字符串参数的路由。例如
reverse('admin:program_program_change', 'myapp.urls', args=(u'__fk__',))
解决方案是通过覆盖其 get_urls
方法,将另一个具有相同名称的管理路由注入 ProgramAdmin
模型,如下所示:
class ProgramAdmin(admin.ModelAdmin):
...
...
def get_urls(self):
from django.conf.urls import url
from functools import update_wrapper
def wrap(view):
def wrapper(*args, **kwargs):
return self.admin_site.admin_view(view)(*args, **kwargs)
wrapper.model_admin = self
return update_wrapper(wrapper, view)
urls = super(ProgramAdmin, self).get_urls()
info = self.model._meta.app_label, self.model._meta.model_name
alt_urls=[
url(r'^(?P<program_pk>\w+)/change/$', wrap(self.change_view), name='%s_%s_change' % info),
]
return urls+alt_urls
现在我们有两个名称相同但路径参数不同的路由例如:
/admin/program/program/<program_pk>/change/ django.contrib.admin.options.change_view admin:program_program_change
admin/program/program/(?P\d+)/change/$
/admin/program/program/<program_pk>/change/ django.contrib.admin.options.change_view admin:program_program_change
admin/program/program/(?P\w+)/change/$
根据上下文,将使用路由之一。