Tuesday, September 4, 2018

Django: Hyperlink from Admin of Model to documentation

Leave a Comment

I have an application which uses the django admin interface extensively.

Some things in the admin GUI need explanations (domain/model specific docs).

We use sphinx and screenshots do explain details.

Is there a generic/automated way to create hyperlinks from the django admin interface of a model instance to the matching part in the docs?

I know that I could alter the admin templates of the models, but somehow I guess someone has a better idea how to solve this in a more professional way.

In my case the docs get hosted on the same server. AFAIK this is needed if you have the big dream, that there are links from the docs into the django application, too (but this is a different question).

What do I mean with "matching part in the docs"?

Imagine I have a model called "Foo".

And I have docs for the model (including images).

Now I would like to have a hyperlink from the admin page of the model to the docs for the model "Foo".

I think this is a very general issue. I think it is a pity that neither the framework nor a third party app help to write integrated docs.

3 Answers

Answers 1

This is the method that I use to create links in the admin site for a particular model.

class YourModelAdmin(admin.ModelAdmin):      def link_to_doc(self,obj):         link = 'https://www.stackoverflow.com'         return u'<a href="%s">%s</a>' % (link, "Link Name")      link_to_doc.allow_tags = True     link_to_doc.short_description = "Link Description for admin"      fields = (          'your_model_fields',          'link_to_doc'                )      readonly_fields = (          'your_model_readonly_fields',          'link_to_doc'                )   admin.site.register(YourModel, YourModelAdmin) 

Answers 2

This problem is specific and there is, as far as I know, very probably no out-of-the-box solution provided by Django.

However, as the requirement is to provide a link (URL) in the model admin, this could be easily accomplished using a virtual property in the model class.

We have a model Foo:

class Foo(models.Model):     bar = models.CharField(max_length=255)     baz = models.IntegerField() 

and model admin FooAdmin:

class FooAdmin(admin.ModelAdmin):     list_display = ('bar', 'baz')     fields = ('bar', 'baz') 

Now we want to provide a link to the documentation from the admin. Assuming that the documentation is automatically generated from the .rst files and followes a generic URL pattern, the docs could be available under a link like this:

http://localhost:8000/docs/foo/ 

Eventually the URL is defined in the urls.py something like this (pseudocode):

url(r'docs/(?P<model>\w+)/$', ViewClass.as_view(), name='docs') 

With these assumptions in mind we add the following things to the model class:

from django.db import models from django.utils.html import format_html from django.urls import reverse  class Foo(models.Model):     bar = models.CharField(max_length=255)     baz = models.IntegerField()      @property     def docurl(self):         url = reverse('docs')         return format_url(             '<a href="{url}">{model}</a>',             url=url,             model=self._meta.model_name         ) 

In the model admin we can use the property docurl as a read-only field:

class FooAdmin(admin.ModelAdmin):     list_display = ('bar', 'baz')     fields = ('bar', 'baz', 'docurl')     readonly_fields = ('docurl',) 

Because the property docurl will be used in all models, it is better to create a base model class for the project, create the property there, and let all other model classes inherit from that class.

Your actual case probably differs from this example, but the basic idea is to retrieve/generate the doc url in a model property and then use the property as a read-only field in the model admin.

The advantage over the other solution, that proposes generating the url directly in the model admin, is putting the business logic into the model. In this way the docurl can be used in many different places.

Answers 3

Don't know what to tell you, but how about you work with the included batteries:

Django’s admindocs app pulls documentation from the docstrings of models, views, template tags, and template filters for any app in INSTALLED_APPS and makes that documentation available from the Django admin.

Since your files are in .rst and not docstrings using sphinx-autodoc (linked for consideration) you can still use this mechanism, by providing a little help string as the class documentation, which then links to the more elaborate docs:

class Joy(models.Model):     """     The purpose of this model is to provide you with daily joy.     How to achieve this is  outlined in the     `documentation <https://docs.example.com/models/Joy>`_.     """ 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment