django.admin.SimpleListFilter。queryset——返回列表?

时间:2021-05-06 01:34:32

I would like to filter a queryset by a function in the model.

我希望通过模型中的一个函数过滤一个queryset。

class CommentAdmin(admin.ModelAdmin):

    class PostedByGuestFilter(admin.SimpleListFilter):

        title = 'Posted by Guest'
        parameter_name = 'posted_by_guest'

        def lookups(self, request, model_admin):
            return (
                (True, 'Yes'),
                (False, 'No'),
            )

        def queryset(self, request, queryset):
            if self.value():
                return [comment for comment in queryset if comment.posted_by_guest()]
            elif not self.value():
                return [comment for comment in queryset if not comment.posted_by_guest()]

Unfortuneately, this implemenation results in django.admin telling me that my database is corrupt. How can I fix this issue?

不幸的是,这种实现导致了django的出现。管理员告诉我我的数据库坏了。我该如何解决这个问题?

django.admin.SimpleListFilter。queryset——返回列表?

2 个解决方案

#1


1  

The problem here is that Django is expecting a queryset and your code is providing a list. You can fix this by wrapping your comprehension in a set:

这里的问题是Django需要一个queryset,而您的代码提供了一个列表。你可以把你的理解用一个集合包装起来:

    def queryset(self, request, queryset):
        if self.value():
            return set(comment for comment in queryset if comment.posted_by_guest())
        elif not self.value():
            return set(comment for comment in queryset if not comment.posted_by_guest())

#2


1  

It’s not optimal (will result in an extra SQL query), and I’d be looking for ways to move the comment.posted_by_guest() logic into SQL if possible (show the body of that method if you’d like help with that), but this ought to work:

它不是最优的(将导致额外的SQL查询),如果可能的话,我将寻找方法将comments .posted_by_guest()逻辑移动到SQL中(如果您愿意,请显示该方法的主体),但这应该是可行的:

def queryset(self, request, queryset):
    expected_value = self.value()
    excludes = []
    for comment in queryset:
        if comment.posted_by_guest() != expected_value:
            excludes.append(comment.id)
    return queryset.exclude(pk__in=excludes)

The Django admin filter API could do with some improvement!

Django管理过滤器API可以做一些改进!

#1


1  

The problem here is that Django is expecting a queryset and your code is providing a list. You can fix this by wrapping your comprehension in a set:

这里的问题是Django需要一个queryset,而您的代码提供了一个列表。你可以把你的理解用一个集合包装起来:

    def queryset(self, request, queryset):
        if self.value():
            return set(comment for comment in queryset if comment.posted_by_guest())
        elif not self.value():
            return set(comment for comment in queryset if not comment.posted_by_guest())

#2


1  

It’s not optimal (will result in an extra SQL query), and I’d be looking for ways to move the comment.posted_by_guest() logic into SQL if possible (show the body of that method if you’d like help with that), but this ought to work:

它不是最优的(将导致额外的SQL查询),如果可能的话,我将寻找方法将comments .posted_by_guest()逻辑移动到SQL中(如果您愿意,请显示该方法的主体),但这应该是可行的:

def queryset(self, request, queryset):
    expected_value = self.value()
    excludes = []
    for comment in queryset:
        if comment.posted_by_guest() != expected_value:
            excludes.append(comment.id)
    return queryset.exclude(pk__in=excludes)

The Django admin filter API could do with some improvement!

Django管理过滤器API可以做一些改进!