Django:SimpleListFilter查询集

时间:2014-07-24 10:37:16

标签: django list filter admin

我有我的模特:

class Category(models.Model):  # family
    name = models.CharField(_('name'), max_length=50)

class Material(models.Model):
    name = models.CharField(_('name'), max_length=50)
    description = models.TextField(_('description'), blank=True)
    slug = models.SlugField()
    category = models.ForeignKey(Category, verbose_name=_('family'))

class Essai_Temperature(models.Model):
    name = models.ForeignKey(Material, verbose_name=_('name'))            

我想在管理员中有一个list_filter,其材料取决于族,例如当选择族(陶瓷,Ni,Ti ......)时,只有与该类别相关的材料列在过滤器选项中< / p>

admin:

class tri_nameFilter(SimpleListFilter):
    title = _('family') 
    parameter_name = 'family'

def lookups(self, request, model_admin):
    allmat = set([c.category for c in Material.objects.all()])
    return [(c, c) for c in allmat]

def queryset(self, request, queryset):
    if self.value():
        return queryset.filter(name=self.value())
    else:
        return queryset

class Essai_TemperatureAdmin(admin.ModelAdmin): 
    list_filter = (tri_nameFilter, 'name__name')

但点击家庭时出现错误

例如,如果我点击'Ni'

invalid literal for int() with base 10: 'Ni

如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

lookups方法中,c.categoryCategory实例,我会避免在查找中使用它,并明确使用id和name属性。

def lookups(self, request, model_admin):
    allmat = set([c.category for c in Material.objects.all()])
    return [(c.id, c.name) for c in allmat]

第二个问题出在您的queryset方法中。

您正在使用过滤器

return queryset.filter(name=self.value())

此处,模型为Essai_Temperaturename是材料的外键。但是,您提供的是字符串Ni(类别的名称),而不是material实例。这不匹配,因此您收到错误:

invalid literal for int() with base 10: 'Ni

您想要过滤材料的类别,因此您需要将查询更改为:

return queryset.filter(name__category=self.value())

如果您不熟悉name__category中使用的双下划线符号,请参阅lookups that span relationships上的Django文档。

答案 1 :(得分:0)

存储外键的方式是通过自动字段(ID)。由于'category'是'material'的外来字段,当你创建一个记录条目时,类别的id被存储,而不是实际名称('Ni'等),因此它期望int和字符串的错误是给出。

您可以做的是,在列表中获取'Ni,ceramic'的ID并使用它来使用'__in'过滤材料记录

这样的事情:

category_ids_list= []
category_names_list = ['Ni', 'ceramic','Ti'] ## From your selected list from front end.
# Iterate through names and get IDs
for category_name in category_names_list:
    category_object = Category.objects.get(name=category_name)
    category_ids_list.append(category_object.id)

Material.objects.filter(category__in=category_ids_list)