Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
122 views
in Technique[技术] by (71.8m points)

python - How do I add a link from the Django admin page of one object to the admin page of a related object?

To deal with the lack of nested inlines in django-admin, I've put special cases into two of the templates to create links between the admin change pages and inline admins of two models.

My question is: how do I create a link from the admin change page or inline admin of one model to the admin change page or inline admin of a related model cleanly, without nasty hacks in the template?

I would like a general solution that I can apply to the admin change page or inline admin of any model.


I have one model, post (not its real name) that is both an inline on the blog admin page, and also has its own admin page. The reason it can't just be inline is that it has models with foreign keys to it that only make sense when edited with it, and it only makes sense when edited with blog.

For the post admin page, I changed part of "fieldset.html" from:

{% if field.is_readonly %}
    <p>{{ field.contents }}</p>
{% else %}
    {{ field.field }}
{% endif %}

to

{% if field.is_readonly %}
    <p>{{ field.contents }}</p>
{% else %}
    {% ifequal field.field.name "blog" %}
        <p>{{ field.field.form.instance.blog_link|safe }}</p>
    {% else %}
        {{ field.field }}
    {% endifequal %}
{% endif %}

to create a link to the blog admin page, where blog_link is a method on the model:

def blog_link(self):
      return '<a href="%s">%s</a>' % (reverse("admin:myblog_blog_change",  
                                        args=(self.blog.id,)), escape(self.blog))

I couldn't find the id of the blog instance anywhere outside field.field.form.instance.

On the blog admin page, where post is inline, I modified part of "stacked.html" from:

<h3><b>{{ inline_admin_formset.opts.verbose_name|title }}:</b>&nbsp;
<span class="inline_label">{% if inline_admin_form.original %}
    {{ inline_admin_form.original }}
{% else %}#{{ forloop.counter }}{% endif %}</span>

to

<h3><b>{{ inline_admin_formset.opts.verbose_name|title }}:</b>&nbsp;
<span class="inline_label">{% if inline_admin_form.original %}
    {% ifequal inline_admin_formset.opts.verbose_name "post" %}
    <a href="/admin/myblog/post/{{ inline_admin_form.pk_field.field.value }}/">
            {{ inline_admin_form.original }}</a>
{% else %}{{ inline_admin_form.original }}{% endifequal %}
{% else %}#{{ forloop.counter }}{% endif %}</span>

to create a link to the post admin page since here I was able to find the id stored in the foreign key field.


I'm sure there is a better, more general way to do add links to admin forms without repeating myself; what is it?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Use readonly_fields:

class MyInline(admin.TabularInline):
    model = MyModel
    readonly_fields = ['link']

    def link(self, obj):
        url = reverse(...)
        return mark_safe("<a href='%s'>edit</a>" % url)

    # the following is necessary if 'link' method is also used in list_display
    link.allow_tags = True

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...