在 django admin 中添加到内联项目的完整更改表单的链接?

发布于 2024-09-02 10:13:40 字数 296 浏览 5 评论 0原文

我有一个对象的标准管理更改表单,以及用于外键关系的常用 StackedInline 表单。我希望能够将每个内联项目链接到其相应的全尺寸更改表单,因为内联项目有自己的内联项目,并且我无法嵌套它们。

我已经尝试了从自定义小部件到自定义模板的所有方法,但无法使任何工作发挥作用。到目前为止,我所看到的以片段形式出现的“解决方案”似乎不适用于内联。我正准备尝试使用 jQuery 进行一些 DOM 黑客攻击,以使其正常工作并继续前进。

我希望我一定错过了一些非常简单的东西,因为这看起来是一个非常简单的任务!

使用 Django 1.2。

I have a standard admin change form for an object, with the usual StackedInline forms for a ForeignKey relationship. I would like to be able to link each inline item to its corresponding full-sized change form, as the inline item has inlined items of its own, and I can't nest them.

I've tried everything from custom widgets to custom templates, and can't make anything work. So far, the "solutions" I've seen in the form of snippets just plain don't seem to work for inlines. I'm getting ready to try some DOM hacking with jQuery just to get it working and move on.

I hope I must be missing something very simple, as this seems like such a simple task!

Using Django 1.2.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

べ映画 2024-09-09 10:13:40

有一个名为 show_change_link 的属性 自 Django 1.8 起。

There is a property called show_change_link since Django 1.8.

本王不退位尔等都是臣 2024-09-09 10:13:40

我在 admin.py 中做了类似以下的事情:

from django.utils.html import format_html
from django.core.urlresolvers import reverse

class MyModelInline(admin.TabularInline):
    model = MyModel

    def admin_link(self, instance):
        url = reverse('admin:%s_%s_change' % (instance._meta.app_label,  
                                              instance._meta.module_name),
                      args=(instance.id,))
        return format_html(u'<a href="{}">Edit</a>', url)
        # … or if you want to include other fields:
        return format_html(u'<a href="{}">Edit: {}</a>', url, instance.title)

    readonly_fields = ('admin_link',)

I did something like the following in my admin.py:

from django.utils.html import format_html
from django.core.urlresolvers import reverse

class MyModelInline(admin.TabularInline):
    model = MyModel

    def admin_link(self, instance):
        url = reverse('admin:%s_%s_change' % (instance._meta.app_label,  
                                              instance._meta.module_name),
                      args=(instance.id,))
        return format_html(u'<a href="{}">Edit</a>', url)
        # … or if you want to include other fields:
        return format_html(u'<a href="{}">Edit: {}</a>', url, instance.title)

    readonly_fields = ('admin_link',)
初与友歌 2024-09-09 10:13:40

目前接受的解决方案很好,但已经过时了。

自 Django 1.3 起,有一个名为 show_change_link = True 的内置属性可以解决此问题。

可以将其添加到任何 StackedInline 或 TabularInline 对象。例如:

class ContactListInline(admin.TabularInline):
    model = ContactList
    fields = ('name', 'description', 'total_contacts',)
    readonly_fields = ('name', 'description', 'total_contacts',)
    show_change_link = True

结果将是这样的:

使用 show_change_link 表格内联

The currently accepted solution here is good work, but it's out of date.

Since Django 1.3, there is a built-in property called show_change_link = True that addresses this issue.

This can be added to any StackedInline or TabularInline object. For example:

class ContactListInline(admin.TabularInline):
    model = ContactList
    fields = ('name', 'description', 'total_contacts',)
    readonly_fields = ('name', 'description', 'total_contacts',)
    show_change_link = True

The result will be something line this:

tabular inline using show_change_link

海的爱人是光 2024-09-09 10:13:40

我遇到了类似的问题,我想出了自定义小部件以及对模型形式的一些调整。这是小部件:

from django.utils.safestring import  mark_safe    

class ModelLinkWidget(forms.Widget):
    def __init__(self, obj, attrs=None):
        self.object = obj
        super(ModelLinkWidget, self).__init__(attrs)

    def render(self, name, value, attrs=None):
        if self.object.pk:
            return mark_safe(
                u'<a target="_blank" href="../../../%s/%s/%s/">%s</a>' %\
                      (
                       self.object._meta.app_label,
                       self.object._meta.object_name.lower(),
                       self.object.pk, self.object
                       )
            )
        else:
            return mark_safe(u'')

现在,由于每个内联的小部件需要在构造函数中获取不同的对象,因此您不能仅以标准方式设置它,而是在 Form 的 init 方法中设置:

class TheForm(forms.ModelForm):
    ...
    # required=False is essential cause we don't
    # render input tag so there will be no value submitted.
    link = forms.CharField(label='link', required=False)

    def __init__(self, *args, **kwargs):
        super(TheForm, self).__init__(*args, **kwargs)
        # instance is always available, it just does or doesn't have pk.
        self.fields['link'].widget = ModelLinkWidget(self.instance)

I had similar problem and I came up with custom widget plus some tweaks to model form. Here is the widget:

from django.utils.safestring import  mark_safe    

class ModelLinkWidget(forms.Widget):
    def __init__(self, obj, attrs=None):
        self.object = obj
        super(ModelLinkWidget, self).__init__(attrs)

    def render(self, name, value, attrs=None):
        if self.object.pk:
            return mark_safe(
                u'<a target="_blank" href="../../../%s/%s/%s/">%s</a>' %\
                      (
                       self.object._meta.app_label,
                       self.object._meta.object_name.lower(),
                       self.object.pk, self.object
                       )
            )
        else:
            return mark_safe(u'')

Now since widget for each inline need to get different object in constructor you can't just set it in standard way, but in Form's init method:

class TheForm(forms.ModelForm):
    ...
    # required=False is essential cause we don't
    # render input tag so there will be no value submitted.
    link = forms.CharField(label='link', required=False)

    def __init__(self, *args, **kwargs):
        super(TheForm, self).__init__(*args, **kwargs)
        # instance is always available, it just does or doesn't have pk.
        self.fields['link'].widget = ModelLinkWidget(self.instance)
你列表最软的妹 2024-09-09 10:13:40

昆汀的上述答案有效,但您还需要指定 fields = ('admin_link',)

Quentin's answer above works, but you also need to specify fields = ('admin_link',)

雪落纷纷 2024-09-09 10:13:40

有一个用于此目的的模块。查看:
django-relatives

There is a module for this purpose. Check out:
django-relatives

话少情深 2024-09-09 10:13:40

我认为:args=[instance.id]应该是args=[instance.pk]。这对我有用!

I think: args=[instance.id] should be args=[instance.pk]. It worked for me!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文