自定义 Django Admin 更改表单外键以包含视图记录
在 django 管理更改表单中选择外键时,我尝试添加一个 href,可以查看添加记录的加号旁边的记录。
我只是为了获取要渲染的 href 而尝试将 admins def render 复制到我自己的自定义小部件文件中,并将其添加到并对其进行子类化:
widgets.py
class RelatedFieldWidgetWrapperLink(RelatedFieldWidgetWrapper):
def render(self, name, value, *args, **kwargs):
rel_to = self.rel.to
info = (rel_to._meta.app_label, rel_to._meta.object_name.lower())
try:
related_url = reverse('admin:%s_%s_add' % info, current_app=self.admin_site.name)
except NoReverseMatch:
info = (self.admin_site.root_path, rel_to._meta.app_label, rel_to._meta.object_name.lower())
related_url = '%s%s/%s/add/' % info
self.widget.choices = self.choices
output = [self.widget.render(name, value, *args, **kwargs)]
if self.can_add_related:
# TODO: "id_" is hard-coded here. This should instead use the correct
# API to determine the ID dynamically.
output.append(u'<a href="%s" class="add-another" id="add_id_%s" onclick="return showAddAnotherPopup(this);"> ' % \
(related_url, name))
output.append(u'<img src="%simg/admin/icon_addlink.gif" width="10" height="10" alt="%s"/></a>' % (settings.ADMIN_MEDIA_PREFIX, _('Add Another')))
output.append(u'<a href="%s" class="testing" id="add_id_%s" onclick="#"> ' % \
(related_url, name))
return mark_safe(u''.join(output))
和 admin.py
formfield_overrides = {models.ForeignKey:{'widget':RelatedFieldWidgetWrapperLink}}
但是我收到以下错误:
类型错误 init() 至少需要 4 个参数(给定 1 个)
以前有人遇到过这个问题吗?
When selecting a foreignkey in the django admin change form I am trying to add an href that can view the record next to the plus that adds the record.
What I've tried just to get the href to render is I've copied out the admins def render into my own custom widgets file and added it to and subclassed it:
widgets.py
class RelatedFieldWidgetWrapperLink(RelatedFieldWidgetWrapper):
def render(self, name, value, *args, **kwargs):
rel_to = self.rel.to
info = (rel_to._meta.app_label, rel_to._meta.object_name.lower())
try:
related_url = reverse('admin:%s_%s_add' % info, current_app=self.admin_site.name)
except NoReverseMatch:
info = (self.admin_site.root_path, rel_to._meta.app_label, rel_to._meta.object_name.lower())
related_url = '%s%s/%s/add/' % info
self.widget.choices = self.choices
output = [self.widget.render(name, value, *args, **kwargs)]
if self.can_add_related:
# TODO: "id_" is hard-coded here. This should instead use the correct
# API to determine the ID dynamically.
output.append(u'<a href="%s" class="add-another" id="add_id_%s" onclick="return showAddAnotherPopup(this);"> ' % \
(related_url, name))
output.append(u'<img src="%simg/admin/icon_addlink.gif" width="10" height="10" alt="%s"/></a>' % (settings.ADMIN_MEDIA_PREFIX, _('Add Another')))
output.append(u'<a href="%s" class="testing" id="add_id_%s" onclick="#"> ' % \
(related_url, name))
return mark_safe(u''.join(output))
and in admin.py
formfield_overrides = {models.ForeignKey:{'widget':RelatedFieldWidgetWrapperLink}}
however I get thefollowing error:
TypeError
init() takes at least 4 arguments (1 given)
Has anyone run into this problem before?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
RelatedFieldWidgetWrapper
小部件和您的子类不适合用作formfield_overrides
中的小部件。__init__
方法具有不同的函数签名,因此会出现TypeError
。如果您查看
django.contrib.admin.options< 中的代码/code>
,可以看到在模型管理的
formfield_for_dbfield
方法中实例化了RelatedFieldWidgetWrapper
小部件,这样它就可以传递参数rel
、admin_site
和can_add_lated
。我认为您可能必须重写模型管理类的
formfield_for_dbfield
方法,并在那里使用自定义的RelatedFieldWidgetWrapperLink
小部件。其他方法
您可能会发现重写
formfield_for_foreignkey
方法比formfield_for_dbfield
更清晰。您可以对
Select
小部件进行子类化,并在其渲染方法中添加链接。然后,您的自定义选择小部件将由RelatedFieldWidgetWrapper
包装。但是,我不确定您是否可以在render
方法的范围内生成view_url
。The
RelatedFieldWidgetWrapper
widget, and your subclass, are not meant to be used as the widget informfield_overrides
. The__init__
methods have different function signatures, hence theTypeError
.If you look at the code in
django.contrib.admin.options
, you can see that theRelatedFieldWidgetWrapper
widget is instantiated in the model admin'sformfield_for_dbfield
method, so that it can be passed the argumentsrel
,admin_site
andcan_add_related
.I think you may have to override your model admin class'
formfield_for_dbfield
method, and use your customRelatedFieldWidgetWrapperLink
widget there.Other approaches
You may find it cleaner to override the
formfield_for_foreignkey
method thanformfield_for_dbfield
.You may be able to subclass the
Select
widget, and add your link in it's render method. Your custom select widget would then be wrapped by theRelatedFieldWidgetWrapper
. However, I am not sure whether you can produce theview_url
inside the scope of therender
method.我稍微改进了 @Alasdair 解决方案:
它使用与
RelatedFieldWidgetWrapper
相同的代码结构和样式。此外,它使用“更改”图标而不仅仅是字符串。当外键无处指向或外键指向未定义管理界面的模型时,它会优雅地生存。I improved @Alasdair solution a bit:
It uses the same code structure and style as
RelatedFieldWidgetWrapper
. Additionally, it uses "change" icon instead of just string. It gracefully survives when foreign key points nowhere or where foreign key points to a model which does not have admin interface defined.