Reputation: 10444
Let's say I have a data model like so: Apple->Fruit->Organic
so Apple has a foreign key to Fruit... and Organic has 3 fields: name, title, level. I'm displaying the 3 fields in a single column as name_title_level. I want to be able to sort the result by clicking on the table header. I've looked at: https://djangosnippets.org/snippets/2110/ and tried it:
class SpecialOrderingChangeList(ChangeList):
def apply_special_ordering(self, queryset):
order_type, order_by = [self.params.get(param, None) for param in ('ot', 'o')]
special_ordering = self.model_admin.special_ordering
if special_ordering and order_type and order_by:
try:
order_field = self.list_display[int(order_by)]
ordering = special_ordering[order_field]
if order_type == 'desc':
ordering = ['-' + field for field in ordering]
queryset = queryset.order_by(*ordering)
except IndexError:
return queryset
except KeyError:
return queryset
return queryset
def get_query_set(self):
queryset = super(SpecialOrderingChangeList, self).get_query_set()
queryset = self.apply_special_ordering(queryset)
return queryset
@admin.register(Apple)
class AppleAdmin(admin.ModelAdmin):
list_display = ('x', 'get_name')
def get_name(self, obj):
return "{}_{}_{}".format(obj.fruit.organic.name,\
obj.fruit.organic.title, obj.fruit.organic.level)
special_ordering = {'name': ('fruit__organic__name', 'fruit__organic__title', 'fruit__organic__level')}
def get_changelist(self, request, **kwargs):
return SpecialOrderingChangeList
I'm not getting any error and the sort feature is not doing anything. The get_query_set method is not being called. Does anyone know how to do this?
Updates: Here is the updated code. Now the method gets called but still there is no sorting functionality. I mean there is no link in the header at all.
models.py:
from django.db import models
class Organic(models.Model):
name = models.CharField(max_length=30)
title = models.CharField(max_length=30)
label = models.CharField(max_length=30)
def __unicode__(self):
return self.name
class Fruit(models.Model):
organic = models.ForeignKey(Organic)
def __unicode__(self):
return self.organic.name
class Apple(models.Model):
fruit = models.ForeignKey(Fruit)
color = models.CharField(max_length=30)
def __unicode__(self):
return self.color
admin.py:
from django.contrib import admin
from .models import *
from django.contrib.admin.views.main import ChangeList
@admin.register(Organic)
class OrganicAdmin(admin.ModelAdmin):
pass
@admin.register(Fruit)
class FruitAdmin(admin.ModelAdmin):
pass
class SpecialOrderingChangeList(ChangeList):
def apply_special_ordering(self, queryset):
order_type, order_by = [self.params.get(param, None) for param in ('ot', 'o')]
special_ordering = self.model_admin.special_ordering
if special_ordering and order_type and order_by:
try:
order_field = self.list_display[int(order_by)]
ordering = special_ordering[order_field]
if order_type == 'desc':
ordering = ['-' + field for field in ordering]
queryset = queryset.order_by(*ordering)
except IndexError:
return queryset
except KeyError:
return queryset
return queryset
def get_queryset(self, request):
queryset = super(SpecialOrderingChangeList, self).get_queryset(request)
queryset = self.apply_special_ordering(queryset)
return queryset
@admin.register(Apple)
class AppleAdmin(admin.ModelAdmin):
list_display = ('color', 'get_name')
def get_name(self, obj):
return "{}_{}_{}".format(obj.fruit.organic.name,\
obj.fruit.organic.title, obj.fruit.organic.label)
special_ordering = {'name': ('fruit__organic__name', 'fruit__organic__title', 'fruit__organic__label')}
def get_changelist(self, request, **kwargs):
return SpecialOrderingChangeList
Upvotes: 0
Views: 610