1

I've been asked to add in the admin site of a Django project a new section that will gather information from several models (as it were a Database view) but I'm not allowed to change or add tables/views in the db.

Checking similar questions custom page for Django admin in SO, I've ended up trying to create a "fake" model that won't be managed by Django and adding custom urls in get_urls method.

Let code explain itself:

core/admin.py

class ConfigurationOverview(Model):
    aa = ForeignKey(ModelA, on_delete=DO_NOTHING)
    bb = ForeignKey(ModelB, on_delete=DO_NOTHING)
    cc = ForeignKey(ModelC, on_delete=DO_NOTHING)

    class Meta:
        # Django won't consider this model
        managed = False
        # link to the index page at /admin
        verbose_name = 'Configuration overview'
        app_label = 'core'

     @staticmethod
     def all():
         # gather info from ModelA, ModelB, ModelC and create a collection of ConfigurationOverviews
         return []

@register(ConfigurationOverview)
class ConfigurationOverviewAdmin(ModelAdmin):

    def get_urls(self):
        urls = super(ConfigurationOverviewAdmin, self).get_urls()

        my_urls = [
            url(
                r'^$',  # /admin/core/configurationoverview/
                self.admin_site.admin_view(self.list_view),
                name='core_configurationoverview_list'
            )
        ]
        return my_urls + urls

    def list_view(self, request):
        context = {
            'configuration_overviews': ConfigurationOverview.all(),
        }
        return render(request,
                      "admin/core/configurationoverview/change_list.html",
                      context)

templates/admin/core/configurationoverview/change_list.html

{% extends "admin/change_list.html" %}

{% block content %}
AAAA
{% endblock %}

But when accesing /admin/core/configurationoverview/ I'm getting

NoReverseMatch at /admin/core/configurationoverview/
Reverse for 'app_list' with keyword arguments '{'app_label': ''}' not found. 1

but I've defined app_label: core! any hint?

* EDIT *

This is the empty migration I ran:

class Migration(migrations.Migration):
    dependencies = [...]
    operations = [
        migrations.CreateModel(
            name='ConfigurationOverview',
            fields=[],
            options={
                'managed': False,
                'verbose_name': 'Configuration overview'
            },
        ),
    ]
Manu Artero
  • 9,238
  • 6
  • 58
  • 73
  • Is there a table/view in the database to represent the entity ConfigurationOverview? Because even though the model is not being managed by django the table/view must exists. – grouchoboy Apr 24 '19 at 14:24
  • no there isn't... (attaching the empty migration)... how would you face this problem instead? (thanks) – Manu Artero Apr 24 '19 at 14:25

1 Answers1

1

You can try to add a regular view and require the user to be a staff member.

views.py

from django.contrib.admin.views.decorators import staff_member_required

@staff_member_required
def configuration_overview(request):
    aa = ModelA.objects.all() # customize this queryset if neccesary, paginate ...
    bb = ModelB.objects.all() # customize this queryset if neccesary, paginate ...
    cc = ModelC.objects.all() # customize this queryset if neccesary, paginate ...

    return render(request, 'admin/core/configurationoverview/change_list.html', context={'aa': aa, 'bb': bb, 'cc': cc})

urls.py

urlpatterns = [
    ###
    path('admin/configuration', views.configuration_overview) # customize the path you want
    ###
]
grouchoboy
  • 1,016
  • 8
  • 12
  • 1
    is it possible with this solution to add that page in the admin site and having that view as any admin view "feeling"? – Manu Artero Apr 24 '19 at 15:17
  • I am wondering the same as @Manu - if we only have something in views.py, how can we add a link to that URL from the primary `/admin` view? In particular, how would we tell Django which app to put the link under? – Addison Klinke Jul 28 '20 at 17:17