Consider the simple model:
class Item(models.Model):
name = models.CharField(...)
unit_cost = models.DecimalField(...)
unit_price = models.DecimalField(...)
It has the following admin class:
class ItemAdmin(admin.ModelAdmin):
def queryset(self, request):
qs = self.model._default_manager.get_query_set()
qs2 = self.model._default_manager.raw('''
SELECT
"stock_item"."id",
"stock_item"."name",
"stock_item"."unit_cost",
"stock_item"."unit_price"
FROM
"stock_item"
''')
qs3 = RawQuerySet('''
SELECT
"stock_item"."id",
"stock_item"."name",
"stock_item"."unit_cost",
"stock_item"."unit_price"
FROM
"stock_item"
''', self.model)
return qs # WORKS
return qs2 # DOESN'T WORK
return qs3 # DOESN'T WORK
I am overriding the queryset() method so as to control the behavior of the admin list view. I want to perform a raw sql query in queryset(), map the results back to the Item model before sending them to the list view. The problem is that returning qs2 or qs3 generates the following error in the template (without throwing an exception):
Database error
Something's wrong with your database installation. Make sure the appropriate database tables have been created, and make sure the database is readable by the appropriate user.
Mind you that running the raw query in a separate script works, for example:
items = Item._default_manager.raw('''
SELECT
"stock_item"."id",
"stock_item"."name",
"stock_item"."unit_cost",
"stock_item"."unit_price"
FROM
"stock_item"
''')
for item in items:
print item.name, item.unit_price # WORKS!
In fact, I have a bigger ambition, to be able to create a sort of a 'virtual model' that should not have a corresponding database table the purpose of which is to encapsulate sql projection queries in its admin class (so that the model can be displayed in it's admin list view).
I have tried another approach, not using ItemAdmin at all but instead using:
class ItemManager(models.Manager):
def get_query_set(self):
return Item._default_manager.raw('''
SELECT
"stock_item"."id",
"stock_item"."name",
"stock_item"."unit_cost",
"stock_item"."unit_price"
FROM
"stock_item"
''')
with:
class Item(models.Model):
objects = ItemManager()
etc...
But now I am getting a template exception in admin list view:
'RawQuerySet' object has no attribute 'complex_filter'
What to do? Thanks...