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> <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> <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?
If needed, run the Django app again with python manage.py runserver 0.0. 0.0:8000 and then navigate once more to the URL http:// your-server-ip :8000/admin/ to get to the admin login page. Then log in with the username and password and password you just created.
One of the most powerful parts of Django is the automatic admin interface. It reads metadata from your models to provide a quick, model-centric interface where trusted users can manage content on your site. The admin's recommended use is limited to an organization's internal management tool.
Django does a pretty good job of creating a basic admin site using the information from the registered models: Each model has a list of individual records, identified by the string created with the model's __str__ () method, and linked to detail views/forms for editing.
By default, this is “Django administration”. The text to put at the end of each admin page’s <title> (a string). By default, this is “Django site admin”. The URL for the “View site” link at the top of each admin page.
First, Django actions are designed for a specific purpose. From the docs: In these cases, Django’s admin lets you write and register “actions” – functions that get called with a list of objects selected on the change list page. If you’re just looking to display a list of names, that’s not an admin function, that’s an ordinary view.
One of the most powerful parts of Django is the automatic admin interface. It reads metadata from your models to provide a quick, model-centric interface where trusted users can manage content on your site.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With