Search code examples
pythondjangoadmin

Django create admin list from raw query


I'm willing to create queryset list template in the admin

The queryset is obtained through a cursor.execute() so a fake model might be needed is needed.

Basically I just want to take advantage of the pagination and filter functionality Django admin list provides.

Here's the relevant part of my code

models.py

class Query(object):

   def __init__(self, sql):

       self.sql = sql


   def execute_query(self):

        cursor = connection.cursor()
        start_time = time()

        try:
            cursor.execute(self.sql)
        except DatabaseError as e:
            cursor.close()
            raise e

        return cursor, ((time() - start_time) * 1000)

admin.py

 class QueryAdmin(admin.ModelAdmin):
 ....


admin.site.register(Query, QueryAdmin)

Solution

  • If you are just trying to use the django admin functionality to make use of it's pagination and filtering features, you will find yourself spending far more time on it than you would if you used django pagination. In the the very first thing you will find is that both pagination and filtering will not work with cursor.execute

    If you do need some sort of admin functionality here, read on.

    The preferred way to use a custom queryset in django admin is to override the get_queryset method in the admin class.

    The get_queryset method on a ModelAdmin returns a QuerySet of all model instances that can be edited by the admin site. One use case for overriding this method is to show objects owned by the logged-in user:

    So our code would be like

    class QueryAdmin(admin.ModelAdmin):
        def queryset(self, request, queryset):
    
            return SomeModel.objects.raw('SOME QUERY')
    

    If you wanted to return a custom raw query set, you would do that here by using the raw method call on the object's manager. It's much more preferable to using cursor.execute. You will actually need such a method (objects.raw) instead of execute to make use of some of the django admin functionality.

    Even now you will find that pagination doesn't work. Then you will need to do this: django pagination and RawQuerySet